nuclei-templates/headless/webpack-sourcemap.yaml

221 lines
5.5 KiB
YAML

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
tags: javascript,webpack,sourcemaps
headless:
- 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: 490a00463044022037d26b0bf4e1e46e77bcae5925a09f8dd5e8ea38894b06c3a450cac92ae803b5022016539aa792c7f25f571a45c194e983fa46aa24f8980c2829025ebf9e7c4e3b1c:922c64590222798bb761d5b6d8e72950