2024-06-02 20:11:40 +04:00
id : webpack-sourcemap
2024-04-08 12:10:06 +12:00
info :
2024-06-02 20:11:40 +04:00
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.
2024-04-08 12:10:06 +12:00
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
2024-06-07 10:04:29 +00:00
metadata :
max-request : 9
2025-10-17 14:17:02 +02:00
tags : javascript,webpack,sourcemaps,headless,vuln
2024-04-08 12:10:06 +12:00
headless :
- steps :
- args :
url : "{{BaseURL}}"
action : navigate
2024-06-02 20:11:40 +04:00
2024-04-08 12:10:06 +12:00
- action : sleep
args :
duration : 10
2024-06-02 20:11:40 +04:00
2024-04-08 12:10:06 +12:00
- action : script
name : extract
args :
code : |
2024-06-02 20:11:40 +04:00
() => {
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])];
}
2024-04-08 12:10:06 +12:00
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":'
2024-06-02 20:11:40 +04:00
2024-04-08 12:10:06 +12:00
- 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":'
2024-06-02 20:11:40 +04:00
2024-04-08 12:10:06 +12:00
- 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":'
2024-06-02 20:11:40 +04:00
2024-04-08 12:10:06 +12:00
- 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":'
2024-06-02 20:11:40 +04:00
2024-04-08 12:10:06 +12:00
- type : status
status :
- 200
2025-10-26 16:17:34 +00:00
# digest: 4a0a00473045022059f0403868fbb8c1f4d6cc1d110868eed994a1c8ab4afd5dc44197827f24a0740221009ce2c955de870dbfed2410ab4840cc2f2466ea28852519ae8bdb8044a76d214a:922c64590222798bb761d5b6d8e72950