1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
From: Chris Rowe <chris@pebblepad.co.uk>
Date: Tue, 17 Sep 2024 16:49:06 +0100
Subject: CVE-2024-21490 and CVE-2024-8372
Fix ReDoS vulnerability with ng-srcset
Fix also CVE-2024-8372 by sanitizing
origin: backport, https://github.com/PebblePad/angular.js/commit/2111de19f71fa70ed8aa0a0797612718a6f6e867
bug: https://codepen.io/herodevs/full/xxoQRNL/0072e627abe03e9cda373bc75b4c1017
bug-debian: https://bugs.debian.org/1088804
bug-cve: https://www.cve.org/CVERecord?id=CVE-2024-21490
---
src/ng/compile.js | 46 ++++++++--------------------------------------
1 file changed, 8 insertions(+), 38 deletions(-)
diff --git a/src/ng/compile.js b/src/ng/compile.js
index e48b5a9..b90318f 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -2086,46 +2086,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
throw $compileMinErr('srcset', 'Can\'t pass trusted values to `{0}`: "{1}"', invokeType, value.toString());
}
- // Such values are a bit too complex to handle automatically inside $sce.
- // Instead, we sanitize each of the URIs individually, which works, even dynamically.
-
- // It's not possible to work around this using `$sce.trustAsMediaUrl`.
- // If you want to programmatically set explicitly trusted unsafe URLs, you should use
- // `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the
- // `ng-bind-html` directive.
-
- var result = '';
-
- // first check if there are spaces because it's not the same pattern
- var trimmedSrcset = trim(value);
- // ( 999x ,| 999w ,| ,|, )
- var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
- var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;
-
- // split srcset into tuple of uri and descriptor except for the last item
- var rawUris = trimmedSrcset.split(pattern);
-
- // for each tuples
- var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
- for (var i = 0; i < nbrUrisWith2parts; i++) {
- var innerIdx = i * 2;
- // sanitize the uri
- result += $sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));
- // add the descriptor
- result += ' ' + trim(rawUris[innerIdx + 1]);
+ var srcSetValues = value.split(',')
+ var sanitisedSrcSet = [];
+ for (const srcSetValue of srcSetValues) {
+ const wellTrimmedSrcSetValue = srcSetValue.trim().replace(/\s{2,}/, ' ');
+ const srcSplit = wellTrimmedSrcSetValue.split(' ');
+ const uri = $sce.getTrustedMediaUrl(srcSplit[0]);
+ sanitisedSrcSet.push(`${uri}${srcSplit[1] !== undefined ? " " + srcSplit[1] : ""}`)
}
- // split the last item into uri and descriptor
- var lastTuple = trim(rawUris[i * 2]).split(/\s/);
-
- // sanitize the last uri
- result += $sce.getTrustedMediaUrl(trim(lastTuple[0]));
-
- // and add the last descriptor if any
- if (lastTuple.length === 2) {
- result += (' ' + trim(lastTuple[1]));
- }
- return result;
+ return sanitisedSrcSet.join(',');
}
|