diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 132873cadb4e..d8aa7428943d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,10 @@ jobs: grep -q "CVE-2022-25869" build/angular-sanitize.js || (echo "$sanitize style fix missing!" && exit 1) echo "✓ $sanitize style fix present" + # Verify SCE regex anchoring fix (CVE-2026-11998) + grep -q "CVE-2026-11998" angular.js || (echo "SCE regex anchor fix missing!" && exit 1) + echo "✓ SCE regex anchor fix present" + # Aggregate gate — single stable required check `gate` (see brickhouse-tech/github-ops). gate: name: gate diff --git a/README.md b/README.md index 4c7376584fa6..d976d4c40724 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ [![npm version](https://img.shields.io/npm/v/@brickhouse-tech/angular-lts?logo=npm)](https://www.npmjs.com/package/@brickhouse-tech/angular-lts) [![npm downloads](https://img.shields.io/npm/dm/@brickhouse-tech/angular-lts)](https://www.npmjs.com/package/@brickhouse-tech/angular-lts) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) -[![CVEs Patched](https://img.shields.io/badge/CVEs%20Patched-11-green)](https://github.com/brickhouse-tech/angular.js/blob/master/SECURITY.md) +[![CVEs Patched](https://img.shields.io/badge/CVEs%20Patched-12-green)](https://github.com/brickhouse-tech/angular.js/blob/master/SECURITY.md) -> **Production-ready security patches for AngularJS 1.x** — All 11 known CVEs patched. Zero code changes required. Open source alternative to $15K–$50K/year commercial support. +> **Production-ready security patches for AngularJS 1.x** — All 12 known CVEs patched. Zero code changes required. Open source alternative to $15K–$50K/year commercial support. **[Try the Live Demo →](https://brickhouse-tech.github.io/angular-lts-demo/)** @@ -32,7 +32,7 @@ Most enterprises face three bad options: **@brickhouse-tech/angular-lts** is a community-maintained fork that patches all known security vulnerabilities in AngularJS 1.x. -✅ **All 11 CVEs patched** — 2 HIGH, 9 MEDIUM severity vulnerabilities fixed +✅ **All 12 CVEs patched** — 3 HIGH, 9 MEDIUM severity vulnerabilities fixed ✅ **Drop-in replacement** — Same API, same behavior, zero code changes ✅ **MIT licensed** — Free and open source, forever ✅ **Actively maintained** — CI/CD, npm provenance, GitHub security advisories @@ -57,6 +57,7 @@ Most enterprises face three bad options: | 9 | [SNYK-JS-ANGULAR-2772735](https://security.snyk.io/vuln/SNYK-JS-ANGULAR-2772735) | Medium | 5.3 | ReDoS DATE_FORMATS | ✅ Fixed in 1.8.4+ | | 10 | [CVE-2022-25869](https://nvd.nist.gov/vuln/detail/CVE-2022-25869) | Medium | 6.1 | $sanitize bypass style (IE/Edge) | ✅ Fixed in 1.8.4+ | | 11 | [CVE-2022-25844](https://nvd.nist.gov/vuln/detail/CVE-2022-25844) / [CVE-2020-7676](https://nvd.nist.gov/vuln/detail/CVE-2020-7676) / [CVE-2020-7212](https://nvd.nist.gov/vuln/detail/CVE-2020-7212) | High+Medium | 7.5 | ReDoS + XSS + Proto Pollution | ✅ Fixed in 1.8.4+ | +| 12 | [CVE-2026-11998](https://nvd.nist.gov/vuln/detail/CVE-2026-11998) | **High** | 7.6 | SCE resource URL policy bypass (XSS) | ✅ Fixed in 1.10.3+ | **All patches tested and verified.** Full details in [SECURITY.md](SECURITY.md). @@ -99,7 +100,7 @@ HeroDevs offers commercial Extended Support for AngularJS (NES). It's a solid op | Feature | @brickhouse-tech/angular-lts | HeroDevs NES | |---------|------------------------------|--------------| | **Price** | **Free (MIT)** | **$15,000–$50,000+/year** | -| **Security patches** | ✅ All 11 CVEs patched | ✅ All known CVEs patched | +| **Security patches** | ✅ All 12 CVEs patched | ✅ All known CVEs patched | | **Drop-in replacement** | ✅ Zero code changes | ✅ Zero code changes | | **Open source** | ✅ MIT license, public repo | ❌ Proprietary, closed source | | **npm package** | ✅ Public npm | ✅ Private npm registry | diff --git a/angular.js b/angular.js index 315ffdb7841c..d2ede62cedc3 100644 --- a/angular.js +++ b/angular.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.9.2-local+sha.4af6941da + * @license AngularJS v1.10.4-local+sha.ed73bd9bd * (c) 2010-2020 Google LLC. http://angularjs.org * License: MIT */ @@ -99,7 +99,7 @@ function isValidObjectMaxDepth(maxDepth) { function minErr(module, ErrorConstructor) { ErrorConstructor = ErrorConstructor || Error; - var url = 'https://errors.angularjs.org/1.9.2-local+sha.4af6941da/'; + var url = 'https://errors.angularjs.org/1.10.4-local+sha.ed73bd9bd/'; var regex = url.replace('.', '\\.') + '[\\s\\S]*'; var errRegExp = new RegExp(regex, 'g'); @@ -2836,10 +2836,10 @@ function toDebugString(obj, maxDepth) { var version = { // These placeholder strings will be replaced by grunt's `build` task. // They need to be double- or single-quoted. - full: '1.9.2-local+sha.4af6941da', + full: '1.10.4-local+sha.ed73bd9bd', major: 1, - minor: 9, - dot: 2, + minor: 10, + dot: 4, codeName: 'snapshot' }; @@ -2991,7 +2991,7 @@ function publishExternalAPI(angular) { }); } ]) - .info({ angularVersion: '1.9.2-local+sha.4af6941da' }); + .info({ angularVersion: '1.10.4-local+sha.ed73bd9bd' }); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -20128,7 +20128,10 @@ function adjustMatcher(matcher) { // The only other type of matcher allowed is a Regexp. // Match entire URL / disallow partial matches. // Flags are reset (i.e. no global, ignoreCase or multiline) - return new RegExp('^' + matcher.source + '$'); + // The source is wrapped in a non-capturing group so that top-level + // alternations (e.g. /a|b/) cannot escape the ^...$ anchors and + // partially match a URL (CVE-2026-11998). + return new RegExp('^(?:' + matcher.source + ')$'); } else { throw $sceMinErr('imatcher', 'Matchers may only be "self", string patterns or RegExp objects'); diff --git a/angular.min.js b/angular.min.js index 89648a596261..f2269b27abef 100644 --- a/angular.min.js +++ b/angular.min.js @@ -1,6 +1,6 @@ /** - * @license AngularJS v1.9.2-local+sha.4af6941da + * @license AngularJS v1.10.4-local+sha.ed73bd9bd * (c) 2010-2020 Google LLC. http://angularjs.org * License: MIT */ -!function(t){"use strict";var e={objectMaxDepth:5,urlErrorParamsEnabled:!0};function n(t){if(!_(t))return e;L(t.objectMaxDepth)&&(e.objectMaxDepth=r(t.objectMaxDepth)?t.objectMaxDepth:NaN),L(t.urlErrorParamsEnabled)&&Y(t.urlErrorParamsEnabled)&&(e.urlErrorParamsEnabled=t.urlErrorParamsEnabled)}function r(t){return H(t)&&t>0}function i(t,n){n=n||Error;var r="https://errors.angularjs.org/1.9.2-local+sha.4af6941da/",i=r.replace(".","\\.")+"[\\s\\S]*",o=new RegExp(i,"g");return function(){var i,a,s=arguments[0],u=arguments[1],c="["+(t?t+":":"")+s+"] ",l=ht(arguments,2).map(function(t){return Bt(t,e.objectMaxDepth)});if(c+=u.replace(/\{\d+\}/g,function(t){var e=+t.slice(1,-1);return e=0&&e-1 in t||"function"==typeof t.item)}function E(t,e,n){var r,i;if(t)if(G(t))for(r in t)"prototype"!==r&&"length"!==r&&"name"!==r&&t.hasOwnProperty(r)&&e.call(n,t[r],r,t);else if(z(t)||x(t)){var o="object"!=typeof t;for(r=0,i=t.length;r=0&&t.splice(n,1),n}function at(t,e,n){var i,o,a=[],s=[];if(n=r(n)?n:NaN,e){if((o=e)&&H(o.length)&&Q.test(m.call(o))||(i=e,"[object ArrayBuffer]"===m.call(i)))throw y("cpta","Can't copy! TypedArray destination cannot be mutated.");if(t===e)throw y("cpi","Can't copy! Source and destination are identical.");return z(e)?e.length=0:E(e,function(t,n){"$$hashKey"!==n&&delete e[n]}),a.push(t),s.push(e),u(t,e,n)}return c(t,n);function u(t,e,n){if(--n<0)return"...";var r,i=e.$$hashKey;if(z(t))for(var o=0,a=t.length;o2?ht(arguments,2):[];return!G(e)||e instanceof RegExp?e:n.length?function(){return arguments.length?e.apply(t,ft(n,arguments,0)):e.apply(t,n)}:function(){return arguments.length?e.apply(t,arguments):e.call(t)}}function dt(e,n){var r=n;return"string"==typeof e&&"$"===e.charAt(0)&&"$"===e.charAt(1)?r=void 0:J(n)?r="$WINDOW":n&&t.document===n?r="$DOCUMENT":Z(n)&&(r="$SCOPE"),r}function $t(t,e){if(!D(t))return H(e)||(e=e?2:null),JSON.stringify(t,dt,e)}function vt(t){return F(t)?JSON.parse(t):t}var mt=/:/g;function gt(t,e){t=t.replace(mt,"");var n=Date.parse("Jan 01, 1970 00:00:00 "+t)/6e4;return N(n)?e:n}function yt(t,e){return(t=new Date(t.getTime())).setMinutes(t.getMinutes()+e),t}function bt(t,e,n){n=n?-1:1;var r=t.getTimezoneOffset();return yt(t,n*(gt(e,r)-r))}function wt(t){t=a(t).clone().empty();var e=a("
").append(t).html();try{return t[0].nodeType===Ft?h(e):e.match(/^(<[^>]+>)/)[1].replace(/^<([\w-]+)/,function(t,e){return"<"+h(e)})}catch(t){return h(e)}}function xt(t){try{return decodeURIComponent(t)}catch(t){}}function Et(t){var e={};return E((t||"").split("&"),function(t){var n,r,i;t&&(r=t=t.replace(/\+/g,"%20"),-1!==(n=t.indexOf("="))&&(r=t.substring(0,n),i=t.substring(n+1)),L(r=xt(r))&&(i=!L(i)||xt(i),f.call(e,r)?z(e[r])?e[r].push(i):e[r]=[e[r],i]:e[r]=i))}),e}function Ct(t){return St(t,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function St(t,e){return encodeURIComponent(t).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,e?"%20":"+")}var kt=["ng-","data-ng-","ng:","x-ng-"];var At=function(e){var n=e.currentScript;if(!n)return!0;if(!(n instanceof t.HTMLScriptElement||n instanceof t.SVGScriptElement))return!1;var r=n.attributes;return[r.getNamedItem("src"),r.getNamedItem("href"),r.getNamedItem("xlink:href")].every(function(t){if(!t)return!0;if(!t.value)return!1;var n=e.createElement("a");if(n.href=t.value,e.location.origin===n.origin)return!0;switch(n.protocol){case"http:":case"https:":case"ftp:":case"blob:":case"file:":case"data:":return!0;default:return!1}})}(t.document);function Ot(e,n){var r,i,o={};if(E(kt,function(t){var n=t+"app";!r&&e.hasAttribute&&e.hasAttribute(n)&&(r=e,i=e.getAttribute(n))}),E(kt,function(t){var n,o=t+"app";!r&&(n=e.querySelector("["+o.replace(":","\\:")+"]"))&&(r=n,i=n.getAttribute(o))}),r){if(!At)return void t.console.error("AngularJS: disabling automatic bootstrap.