Webpack Sourcemap
ID: webpack-sourcemap
Severity: low
Author: lucky0x0d,PulseSecurity.co.nz
Tags: javascript,webpack,sourcemaps,headless
Description
Section titled “Description”Detects if Webpack source maps are exposed.
YAML Source
Section titled “YAML Source”id: webpack-sourcemap
info: name: Webpack Sourcemap author: lucky0x0d,PulseSecurity.co.nz severity: low description: | Detects if Webpack source maps are exposed. impact: | Exposure of source maps can leak sensitive information about the application's source code and potentially aid attackers in identifying vulnerabilities. remediation: | Ensure that Webpack source maps are not exposed to the public by configuring the server to restrict access to them. reference: - https://pulsesecurity.co.nz/articles/javascript-from-sourcemaps - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/01-Information_Gathering/05-Review_Web_Page_Content_for_Information_Leakage metadata: max-request: 9 tags: javascript,webpack,sourcemaps,headlessheadless: - steps: - args: url: "{{BaseURL}}" action: navigate
- action: sleep args: duration: 10
- action: script name: extract args: code: | () => { AAA = []; window.performance.getEntriesByType("resource").forEach((element) => { if (element.initiatorType === 'script' || element.initiatorType === 'fetch'|| element.initiatorType === 'xmlhttprequest') {AAA.push(element.name)}}); BBB = [...new Set(Array.from(document.querySelectorAll('script')).map(i => i.src))] CCC = [...new Set(Array.from(document.querySelectorAll('link[as=script]')).map(i => i.href))] return [...new Set([...AAA, ...BBB, ...CCC])]; }
extractors: - type: regex name: allscripts internal: true part: extract regex: - (?i)http(.[~a-zA-Z0-9.\/\-_:]+)flow: | headless(); http("check_base_srcmap_inline"); for (let scripturi of iterate(template["allscripts"])) { set ("scripturi", scripturi); http("check_for_srcmap_header"); http("check_for_srcmap_inline"); http("check_for_srcmap_url"); for (let mapuri of iterate(template["allmaps"])) { set ("mapuri", mapuri); http("fetch_absolute_srcmap"); http("fetch_relative_srcmap"); http("fetch_root_relative_srcmap"); http("fetch_noscheme_srcmaps"); }; set ("allmaps", null); };
http: - method: GET id: check_base_srcmap_inline disable-cookie: true redirects: true path: - '{{BaseURL}}'
matchers: - type: regex name: Inline_SourceMap regex: - '(?i)sourceMappingURL=.*eyJ2ZXJzaW9uIjo'
- type: regex name: SourceMapConsumer_Present regex: - '(?i)SourceMapConsumer'
- method: GET id: check_for_srcmap_url disable-cookie: true redirects: true path: - '{{scripturi}}'
extractors: - type: regex name: allmaps internal: true group: 1 regex: - (?i)\/\/#\ssourceMappingURL=(.[~a-zA-Z0-9.\/\-_:]+)
- method: GET id: check_for_srcmap_inline disable-cookie: true redirects: true path: - '{{scripturi}}'
matchers: - type: regex name: Inline_SourceMap regex: - '(?i)sourceMappingURL=.*eyJ2ZXJzaW9uIjo'
- type: regex name: SourceMapConsumer_Present regex: - '(?i)SourceMapConsumer'
- method: GET id: check_for_srcmap_header disable-cookie: true redirects: true path: - '{{scripturi}}'
matchers: - type: dsl name: Source_Map_Header dsl: - "regex('(?i)SourceMap', header)" - "status_code != 301 && status_code != 302" condition: and
extractors: - type: kval kval: - X_SourceMap - SourceMap
- method: GET id: fetch_absolute_srcmap disable-cookie: true redirects: true path: - '{{mapuri}}'
matchers-condition: and matchers: - type: word condition: and part: body words: - '"version":' - '"mappings":' - '"sources":'
- type: status status: - 200
- method: GET id: fetch_relative_srcmap disable-cookie: true redirects: true path: - '{{replace_regex(scripturi,"([^/]+$)","")}}{{replace_regex(mapuri,"(^\/+)","")}}'
matchers-condition: and matchers: - type: word condition: and part: body words: - '"version":' - '"mappings":' - '"sources":'
- type: status status: - 200
- method: GET id: fetch_root_relative_srcmap disable-cookie: true redirects: true path: - '{{replace_regex(scripturi,replace_regex(scripturi,"http.+//[^/]+",""),"")}}{{mapuri}}'
matchers-condition: and matchers: - type: word condition: and part: body words: - '"version":' - '"mappings":' - '"sources":'
- type: status status: - 200
- method: GET id: fetch_noscheme_srcmaps disable-cookie: true redirects: true path: - '{{Scheme}}{{mapuri}}'
matchers-condition: and matchers: - type: word condition: and part: body words: - '"version":' - '"mappings":' - '"sources":'
- type: status status: - 200# digest: 490a0046304402201e45881f521fe28ae5da01d0e374a21781e5a502e85301b95d35213289f14e67022025012152c54aeaba12e0d5b17c9ec0540e25d487c82bd7145cbc6a7e5acaeff3:922c64590222798bb761d5b6d8e72950Guide to check the vulnerabilities
Section titled “Guide to check the vulnerabilities”This template is used to detect vulnerabilities in web applications. It can be used with the Nuclei tool to scan for specific patterns or behaviors.
$ nuclei -u "URL" -t "headless/webpack-sourcemap.yaml"