Skip to content

Commit 3e0c35a

Browse files
committed
Fix "ASN.1 OID Integer Truncation" advisory.
- [asn1] Improve OID handling. - Error on parsed OID values larger than `2**32 - 1`. - Error on DER OID values larger than `2**53 - 1 `.
1 parent 1574803 commit 3e0c35a

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
Forge ChangeLog
22
===============
33

4+
## 1.3.2 - 2025-11-xx
5+
6+
### Security
7+
- **MODERATE**: ASN.1 OID Integer Truncation
8+
- An Integer Overflow (CWE-190) vulnerability in node-forge versions 1.3.1
9+
and below enables remote, unauthenticated attackers to craft ASN.1
10+
structures containing OIDs with oversized arcs. These arcs may be decoded
11+
as smaller, trusted OIDs due to 32-bit bitwise truncation, enabling the
12+
bypass of downstream OID-based security decisions.
13+
- Reported by Hunter Wodzenski.
14+
- GHSA ID: [GHSA-65ch-62r8-g69g](https://github.com/digitalbazaar/forge/security/advisories/GHSA-65ch-62r8-g69g)
15+
16+
### Fixed
17+
- [asn1] Improve OID handling.
18+
- Error on parsed OID values larger than `2**32 - 1`.
19+
- Error on DER OID values larger than `2**53 - 1 `.
20+
421
## 1.3.1 - 2022-03-29
522

623
### Fixes

lib/asn1.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,10 @@ asn1.oidToDer = function(oid) {
773773
last = true;
774774
valueBytes = [];
775775
value = parseInt(values[i], 10);
776+
// TODO: Change bitwise logic to allow larger values.
777+
if(value > 0xffffffff) {
778+
throw new Error('OID value too large; max is 32-bits.');
779+
}
776780
do {
777781
b = value & 0x7F;
778782
value = value >>> 7;
@@ -818,8 +822,13 @@ asn1.derToOid = function(bytes) {
818822
// the last byte for each value
819823
var value = 0;
820824
while(bytes.length() > 0) {
825+
// error if 7b shift would exceed Number.MAX_SAFE_INTEGER
826+
// (Number.MAX_SAFE_INTEGER / 128)
827+
if(value > 0x3fffffffffff) {
828+
throw new Error('OID value too large; max is 53-bits.');
829+
}
821830
b = bytes.getByte();
822-
value = value << 7;
831+
value = value * 128;
823832
// not the last byte for the value
824833
if(b & 0x80) {
825834
value += b & 0x7F;

tests/unit/asn1.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,50 @@ var UTIL = require('../../lib/util');
1010
ASSERT.equal(ASN1.oidToDer('1.2.840.113549').toHex(), '2a864886f70d');
1111
});
1212

13+
it('should convert a 32b OID to DER', function() {
14+
ASSERT.equal(ASN1.oidToDer('1.2.4294967295').toHex(), '2a8fffffff7f');
15+
});
16+
17+
it('should not convert a >32b OID to DER', function() {
18+
ASSERT.throws(
19+
function() {
20+
ASN1.oidToDer('1.2.4294967296');
21+
},
22+
/OID value too large; max is 32-bits./
23+
);
24+
});
25+
1326
it('should convert an OID from DER', function() {
1427
var der = UTIL.hexToBytes('2a864886f70d');
1528
ASSERT.equal(ASN1.derToOid(der), '1.2.840.113549');
1629
});
1730

31+
it('should convert a 32b OID from DER', function() {
32+
var der = UTIL.hexToBytes('2a8fffffff7f');
33+
ASSERT.equal(ASN1.derToOid(der), '1.2.4294967295');
34+
});
35+
36+
it('should convert a >32b OID from DER', function() {
37+
var der = UTIL.hexToBytes('2a9080808001');
38+
ASSERT.equal(ASN1.derToOid(der), '1.2.4294967297');
39+
});
40+
41+
it('should convert a max safe int OID from DER', function() {
42+
var der = UTIL.hexToBytes('2a8fffffffffffff7f');
43+
ASSERT.equal(ASN1.derToOid(der), '1.2.9007199254740991');
44+
});
45+
46+
it('should not convert a >max safe int OID from DER', function() {
47+
ASSERT.throws(
48+
function() {
49+
// '1.2.9007199254740992'
50+
var der = UTIL.hexToBytes('2a9080808080808000');
51+
console.log(ASN1.derToOid(der));
52+
},
53+
/OID value too large; max is 53-bits./
54+
);
55+
});
56+
1857
it('should convert INTEGER 0 to DER', function() {
1958
ASSERT.equal(ASN1.integerToDer(0).toHex(), '00');
2059
});

0 commit comments

Comments
 (0)