Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/)**

Expand All @@ -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
Expand All @@ -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).

Expand Down Expand Up @@ -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 |
Expand Down
17 changes: 10 additions & 7 deletions angular.js
Original file line number Diff line number Diff line change
@@ -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
*/
Expand Down Expand Up @@ -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');

Expand Down Expand Up @@ -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'
};

Expand Down Expand Up @@ -2991,7 +2991,7 @@ function publishExternalAPI(angular) {
});
}
])
.info({ angularVersion: '1.9.2-local+sha.4af6941da' });
.info({ angularVersion: '1.10.4-local+sha.ed73bd9bd' });
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Expand Down Expand Up @@ -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');
Expand Down
4 changes: 2 additions & 2 deletions angular.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion angular.min.js.map

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/ng/sce.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,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');
Expand Down
9 changes: 9 additions & 0 deletions test/ng/sceSpecs.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,15 @@ describe('SCE', function() {
it('should should match * and **', function() {
expect(adjustMatcher('*://*.example.com/**').exec('http://www.example.com/path')).not.toBeNull();
});

// CVE-2026-11998: top-level alternations must not escape the ^...$ anchors
it('should anchor the entire regex when the source contains alternations', function() {
var matcher = adjustMatcher(/https:\/\/a\.com|https:\/\/b\.com/);
expect(matcher.exec('https://a.com')).not.toBeNull();
expect(matcher.exec('https://b.com')).not.toBeNull();
expect(matcher.exec('https://a.com.evil.net')).toBeNull();
expect(matcher.exec('evil://x/https://b.com')).toBeNull();
});
});

describe('regex matcher', function() {
Expand Down
Loading