Common Weakness Enumeration

CWE-354

Allowed

Improper Validation of Integrity Check Value

Abstraction: Base · Status: Draft

The product does not validate or incorrectly validates the integrity check values or "checksums" of a message. This may prevent it from detecting if the data has been modified or corrupted in transmission.

251 vulnerabilities reference this CWE, most recent first.

GHSA-4V26-V6CG-G6F9

Vulnerability from github – Published: 2026-03-13 20:04 – Updated: 2026-03-16 22:01
VLAI
Summary
xmlseclibs: Missing AES-GCM Authentication Tag Validation on Encrypted Nodes Allows for Unauthorized Decryption
Details

Summary

XML nodes encrypted with either aes-128-gcm, aes-192-gcm, or aes-256-gcm lack validation of the authentication tag length. An attacker can use this to brute-force an authentication tag, recover the GHASH key, and decrypt the encrypted nodes. It also allows to forge arbitrary ciphertexts without knowing the encryption key.

Details

When decrypting with either aes-128-gcm, aes-192-gcm, or aes-256-gcm here, the $authTag is set from a substr(), but never has its length validated (it should be validated with something like strlen($authTag) == self::AUTHTAG_LENGTH). For that reason, a shorter than expected data blob will allow for the $authTag to have as short a tag as only one byte (see PHP's documentation).

See this example:

function test($data) {
    $ivSize = 12;
    $tagSize = 16;

    $iv = substr($data, 0, $ivSize);
    $data = substr($data, $ivSize);
    $offset = 0 - $tagSize;
    $tag = substr($data, $offset);
    $ct = substr($data, 0, $offset);

    echo 'IV: "' . $iv . '"' . PHP_EOL;
    echo 'Tag: "' . $tag . '"' . PHP_EOL;
    echo 'CT: "' . $ct . '"' . PHP_EOL;
}

/* Outputs:
php > test('myNonceNoncet');
IV: "myNonceNonce"
Tag: "t"
CT: ""
php > test('myNonceNonceta');
IV: "myNonceNonce"
Tag: "ta"
CT: ""
php > test('myNonceNoncetag');
IV: "myNonceNonce"
Tag: "tag"
CT: ""
*/

With a legit ciphertext in hand, this is enough to recover the GHASH key. With that key, any authenticated tags can be computed offline which allows for decryption of the ciphertext and forgery of arbitrary ciphertexts.

PoC

  1. Setup a server expecting XML with an encrypted assertion
  2. Create an XML document with an encrypted assertion (encrypted with aes-256-gcm)

Note: The steps from 3 to 6 are implemented in this exploit script: nonce_reuse_with_fmt_val_oracle.py. You can run the script with sage -python nonce_reuse_with_fmt_val_oracle.py -s 'url-encoded_and_base64-encoded_samlresponse'

  1. Take the content of the <xenc:CipherValue> node and apply the following modifications
    1. Base64-decode the content
    2. Take the first 12 bytes and save them as the nonce
    3. Take the last 16 bytes and save them as the tag
    4. Now brute-force the tag of an empty ciphertext
      1. Loop through all 256 possible byte values (let's call that byte_tag_attempt)
      2. Concatenate together the nonce and the byte_tag_attempt
      3. Base64-encode the result
      4. Replace the content of the <xenc:CipherValue> node with this result
      5. On http errors 500, we learn that the tag is valid
      6. Do the same for the next byte of the tag until all 16 bytes have been brute-forced
  2. With this new tag and the empty ciphertext, compute the GHASH key (the way to do this has been described in this blog post)
  3. Use this GHASH key to compute authentication tags offline for arbitrary ciphertexts
  4. Decryption is done by observing XML parsing errors that occur after modifying the ciphertext, those can be seen as http errors 500

poc.webm

Impact

The general impact is: - XML nodes encrypted with AES-GCM can be decrypted by observing parsing differences - XML nodes encrypted with AES-GCM can be modified to decrypt to an arbitrary value - The GCM internal GHASH key can be recovered

In cases where the encryption key is embedded in the XML and is encrypted with the Service Provider's public key (like often done with SAML), the last two items don't have a big impact. This is because: - With the Service Provider's public key, an arbitrary ciphertext can be created with a known symmetric key - The symmetric keys are generated on the fly every time the IdP creates a new SAMLResponse

In any case, secrets that are embedded in the XML, whether coming from an IdP, or from another scheme, can be decrypted.

Important: If static symmetric keys are used, as the GHASH key could have leaked, you must rotate those keys.

References

For additional information on the issue, you can refer to this blog post about the OpenSSL issue and how it can be exploited.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "robrichards/xmlseclibs"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.1.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-32313"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-13T20:04:21Z",
    "nvd_published_at": "2026-03-16T14:19:33Z",
    "severity": "HIGH"
  },
  "details": "### Summary\nXML nodes encrypted with either aes-128-gcm, aes-192-gcm, or aes-256-gcm lack validation of the authentication tag length.\nAn attacker can use this to brute-force an authentication tag, recover the [GHASH key](https://en.wikipedia.org/wiki/Galois/Counter_Mode#:~:text=%29%20is%20the-,hash%20key,-%2C%20a%20string%20of), and decrypt the encrypted nodes.\nIt also allows to forge arbitrary ciphertexts without knowing the encryption key.\n\n### Details\nWhen decrypting with either aes-128-gcm, aes-192-gcm, or aes-256-gcm [here](https://github.com/robrichards/xmlseclibs/blob/2bdfd742624d739dfadbd415f00181b4a77aaf07/src/XMLSecurityKey.php#L467-L479), the `$authTag` is set from a `substr()`, but never has its length validated (it should be validated with something like `strlen($authTag) == self::AUTHTAG_LENGTH`).\nFor that reason, a shorter than expected data blob will allow for the `$authTag` to have as short a tag as only one byte (see [PHP\u0027s documentation](https://www.php.net/manual/en/function.openssl-decrypt.php#:~:text=The%20length%20of%20the%20tag%20is%20not%20checked%20by%20the%20function.%20It%20is%20the%20caller%27s%20responsibility%20to%20ensure%20that%20the%20length%20of%20the%20tag%20matches%20the%20length%20of%20the%20tag%20retrieved%20when%20openssl_encrypt()%20has%20been%20called.%20Otherwise%20the%20decryption%20may%20succeed%20if%20the%20given%20tag%20only%20matches%20the%20start%20of%20the%20proper%20tag.)).\n\nSee this example:\n```php\nfunction test($data) {\n    $ivSize = 12;\n    $tagSize = 16;\n\n    $iv = substr($data, 0, $ivSize);\n    $data = substr($data, $ivSize);\n    $offset = 0 - $tagSize;\n    $tag = substr($data, $offset);\n    $ct = substr($data, 0, $offset);\n\n    echo \u0027IV: \"\u0027 . $iv . \u0027\"\u0027 . PHP_EOL;\n    echo \u0027Tag: \"\u0027 . $tag . \u0027\"\u0027 . PHP_EOL;\n    echo \u0027CT: \"\u0027 . $ct . \u0027\"\u0027 . PHP_EOL;\n}\n\n/* Outputs:\nphp \u003e test(\u0027myNonceNoncet\u0027);\nIV: \"myNonceNonce\"\nTag: \"t\"\nCT: \"\"\nphp \u003e test(\u0027myNonceNonceta\u0027);\nIV: \"myNonceNonce\"\nTag: \"ta\"\nCT: \"\"\nphp \u003e test(\u0027myNonceNoncetag\u0027);\nIV: \"myNonceNonce\"\nTag: \"tag\"\nCT: \"\"\n*/\n```\n\nWith a legit ciphertext in hand, this is enough to recover the [GHASH key](https://en.wikipedia.org/wiki/Galois/Counter_Mode#:~:text=%29%20is%20the-,hash%20key,-%2C%20a%20string%20of).\nWith that key, any authenticated tags can be computed offline which allows for decryption of the ciphertext and forgery of arbitrary ciphertexts.\n\n### PoC\n1. Setup a server expecting XML with an encrypted assertion\n    - Run this php script [poc.php](https://github.com/user-attachments/files/24426600/poc.php.txt) with `php -S 127.0.0.1:8888` (taken from [this saml test case](https://github.com/robrichards/xmlseclibs/blob/69fd63080bc47a8d51bc101c30b7cb756862d1d6/tests/saml/saml-decrypt.phpt#L62))\n    - The script expects this private key: [sp-private-key.pem.](https://github.com/user-attachments/files/24426620/sp-private-key.pem.txt)\n2. Create an XML document with an encrypted assertion (encrypted with `aes-256-gcm`)\n    - Here is the `SAMLResponse` used in the video below: [saml_response.txt](https://github.com/user-attachments/files/24426638/saml_response.txt)\n\n**Note:** The steps from 3 to 6 are implemented in this exploit script: [nonce_reuse_with_fmt_val_oracle.py](https://github.com/user-attachments/files/24426645/nonce_reuse_with_fmt_val_oracle.py).\nYou can run the script with `sage -python nonce_reuse_with_fmt_val_oracle.py -s \u0027url-encoded_and_base64-encoded_samlresponse\u0027`\n\n3. Take the content of the `\u003cxenc:CipherValue\u003e` node and apply the following modifications\n    1. Base64-decode the content\n    2. Take the first 12 bytes and save them as the nonce\n    3. Take the last 16 bytes and save them as the tag\n    4. Now brute-force the tag of an empty ciphertext\n        1. Loop through all 256 possible byte values (let\u0027s call that `byte_tag_attempt`)\n        2. Concatenate together the nonce and the `byte_tag_attempt`\n        3. Base64-encode the result\n        4. Replace the content of the `\u003cxenc:CipherValue\u003e` node with this result\n        5. On http errors 500, we learn that the tag is valid\n        6. Do the same for the next byte of the tag until all 16 bytes have been brute-forced\n4. With this new tag and the empty ciphertext, compute the [GHASH key](https://en.wikipedia.org/wiki/Galois/Counter_Mode#:~:text=%29%20is%20the-,hash%20key,-%2C%20a%20string%20of) (the way to do this has been described in this [blog post](https://frereit.de/aes_gcm/))\n5. Use this [GHASH key](https://en.wikipedia.org/wiki/Galois/Counter_Mode#:~:text=%29%20is%20the-,hash%20key,-%2C%20a%20string%20of) to compute authentication tags offline for arbitrary ciphertexts\n6. Decryption is done by observing XML parsing errors that occur after modifying the ciphertext, those can be seen as http errors 500\n\n[poc.webm](https://github.com/user-attachments/assets/2f6e4a7e-4384-4350-b423-7ddd77aa9152)\n\n\n### Impact\nThe general impact is:\n- XML nodes encrypted with AES-GCM can be decrypted by observing parsing differences\n- XML nodes encrypted with AES-GCM can be modified to decrypt to an arbitrary value\n- The GCM internal [GHASH key](https://en.wikipedia.org/wiki/Galois/Counter_Mode#:~:text=%29%20is%20the-,hash%20key,-%2C%20a%20string%20of) can be recovered\n\nIn cases where the encryption key is embedded in the XML and is encrypted with the Service Provider\u0027s public key (like often done with SAML), the last two items don\u0027t have a big impact.\nThis is because: \n- With the Service Provider\u0027s public key, an arbitrary ciphertext can be created with a known symmetric key\n- The symmetric keys are generated on the fly every time the IdP creates a new `SAMLResponse`\n\nIn any case, secrets that are embedded in the XML, whether coming from an IdP, or from another scheme, can be decrypted.\n\n**Important:** If static symmetric keys are used, as the [GHASH key](https://en.wikipedia.org/wiki/Galois/Counter_Mode#:~:text=%29%20is%20the-,hash%20key,-%2C%20a%20string%20of) could have leaked, you must rotate those keys.\n\n### References\nFor additional information on the issue, you can refer to this [blog post](https://sideni.xyz/posts/exploiting_openssl_api/) about the OpenSSL issue and how it can be exploited.",
  "id": "GHSA-4v26-v6cg-g6f9",
  "modified": "2026-03-16T22:01:02Z",
  "published": "2026-03-13T20:04:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/robrichards/xmlseclibs/security/advisories/GHSA-4v26-v6cg-g6f9"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32313"
    },
    {
      "type": "WEB",
      "url": "https://github.com/robrichards/xmlseclibs/commit/03062be78178cbb5e8f605cd255dc32a14981f92"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/robrichards/xmlseclibs"
    },
    {
      "type": "WEB",
      "url": "https://github.com/robrichards/xmlseclibs/releases/tag/3.1.5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "xmlseclibs: Missing AES-GCM Authentication Tag Validation on Encrypted Nodes Allows for Unauthorized Decryption"
}

GHSA-4XM5-4W7J-J8QM

Vulnerability from github – Published: 2022-05-13 01:16 – Updated: 2025-05-06 21:30
VLAI
Details

An issue was discovered in osquery. A maliciously crafted Universal/fat binary can evade third-party code signing checks. By not completing full inspection of the Universal/fat binary, the user of the third-party tool will believe that the code is signed by Apple, but the malicious unsigned code will execute. This issue affects osquery prior to v3.2.7

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-6336"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-12-31T19:29:00Z",
    "severity": "HIGH"
  },
  "details": "An issue was discovered in osquery. A maliciously crafted Universal/fat binary can evade third-party code signing checks. By not completing full inspection of the Universal/fat binary, the user of the third-party tool will believe that the code is signed by Apple, but the malicious unsigned code will execute. This issue affects osquery prior to v3.2.7",
  "id": "GHSA-4xm5-4w7j-j8qm",
  "modified": "2025-05-06T21:30:36Z",
  "published": "2022-05-13T01:16:10Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-6336"
    },
    {
      "type": "WEB",
      "url": "https://www.okta.com/security-blog/2018/06/issues-around-third-party-apple-code-signing-checks"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-56MC-FPWX-P947

Vulnerability from github – Published: 2025-01-17 21:31 – Updated: 2025-01-18 00:30
VLAI
Details

A new feature to prevent Firmware downgrades was recently added to some Lexmark products. A method to override this downgrade protection has been identified.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-50738"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-01-17T21:15:09Z",
    "severity": "CRITICAL"
  },
  "details": "A\u00a0new feature to prevent Firmware downgrades was recently added to some Lexmark products. A method to \noverride this downgrade protection has been identified.",
  "id": "GHSA-56mc-fpwx-p947",
  "modified": "2025-01-18T00:30:48Z",
  "published": "2025-01-17T21:31:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-50738"
    },
    {
      "type": "WEB",
      "url": "https://www.lexmark.com/en_us/solutions/security/lexmark-security-advisories.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-57P2-MGFW-2W94

Vulnerability from github – Published: 2025-04-01 00:30 – Updated: 2025-11-03 21:33
VLAI
Details

This issue was addressed with improved handling of executable types. This issue is fixed in macOS Ventura 13.7.5, macOS Sequoia 15.4, macOS Sonoma 14.7.5. A malicious JAR file may bypass Gatekeeper checks.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-24148"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-03-31T23:15:16Z",
    "severity": "CRITICAL"
  },
  "details": "This issue was addressed with improved handling of executable types. This issue is fixed in macOS Ventura 13.7.5, macOS Sequoia 15.4, macOS Sonoma 14.7.5. A malicious JAR file may bypass Gatekeeper checks.",
  "id": "GHSA-57p2-mgfw-2w94",
  "modified": "2025-11-03T21:33:15Z",
  "published": "2025-04-01T00:30:35Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24148"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/en-us/122373"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/en-us/122374"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/en-us/122375"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2025/Apr/10"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2025/Apr/8"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2025/Apr/9"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-584Q-6J8J-R5PM

Vulnerability from github – Published: 2024-10-21 17:28 – Updated: 2024-10-21 19:09
VLAI
Summary
secp256k1-node allows private key extraction over ECDH
Details

Summary

In elliptic-based version, loadUncompressedPublicKey has a check that the public key is on the curve: https://github.com/cryptocoinjs/secp256k1-node/blob/6d3474b81d073cc9c8cc8cfadb580c84f8df5248/lib/elliptic.js#L37-L39

loadCompressedPublicKey is, however, missing that check: https://github.com/cryptocoinjs/secp256k1-node/blob/6d3474b81d073cc9c8cc8cfadb580c84f8df5248/lib/elliptic.js#L17-L19

That allows the attacker to use public keys on low-cardinality curves to extract enough information to fully restore the private key from as little as 11 ECDH sessions, and very cheaply on compute power

Other operations on public keys are also affected, including e.g. publicKeyVerify() incorrectly returning true on those invalid keys, and e.g. publicKeyTweakMul() also returning predictable outcomes allowing to restore the tweak

Details

The curve equation is Y^2 = X^3 + 7, and it restores Y from X in loadCompressedPublicKey, using Y = sqrt(X^3 + 7), but when there are no valid Y values satisfying Y^2 = X^3 + 7 for a given X, the same code calculates a solution for -Y^2 = X^3 + 7, and that solution also satisfies some other equation Y^2 = X^3 + D, where D is not equal to 7 and might be on a curve with factorizable cardinality, so (X,Y) might be a low-order point on that curve, lowering the number of possible ECDH output values to bruteforcable

Those output values correspond to remainders which can be then combined with Chinese remainder theorem to restore the original value

Endomorphism-based multiplication only slightly hinders restoration and does not affect the fact that the result is low-order

10 different malicious X values could be chosen so that the overall extracted information is 238.4 bits out of 256 bit private key, and the rest is trivially bruteforcable with an additional 11th public key (which might be valid or not -- not significant)

The attacker does not need to receive the ECDH value, they only need to be able to confirm it against a list of possible candidates, e.g. check if using it to decipher block/stream cipher would work -- and that could all be done locally on the attacker side

PoC

Example public key

This key has order 39 One of the possible outcomes for it is a throw, 38 are predictable ECDH values Keys used in full attack have higher order (starting from ~20000), so are very unlikely to cause an error

import secp256k1 from 'secp256k1/elliptic.js'
import { randomBytes } from 'crypto'

const pub = Buffer.from('028ac57f9c6399282773c116ef21f7394890b6140aa6f25c181e9a91e2a9e3da45', 'hex')

const seen = new Set()
for (let i = 0; i < 1000; i++) {
  try {
    seen.add(Buffer.from(secp256k1.ecdh(pub, randomBytes(32))).toString('hex'))
  } catch {
    seen.add('failure also is an outcome')
  }
}

console.log(seen.size) // 39

Full attack

This PoC doesn't list the exact public keys or the code for solver.js intentionally, but this exact code works, on arbitrary random private keys:

// Only the elliptic version is affected, gyp one isn't
// Node.js can use both, Web/RN/bundles always use the elliptic version
import secp256k1 from 'secp256k1/elliptic.js'

import { randomBytes } from 'node:crypto'
import assert from 'node:assert/strict'
import { Solver } from './solver.js'

const privateKey = randomBytes(32)

// The full dataset is precomputed on a single MacBook Air in a few days and can be reused for any private key
const solver = new Solver

// We need to run on 10 specially crafted public keys for this
// Lower than 10 is possible but requires more compute
for (let i = 0; i < 10; i++) {
  const letMeIn = solver.ping() // this is a normal 33-byte Uint8Array, a 02/03-prefixed compressed public key
  assert(letMeIn instanceof Uint8Array) // true
  assert(secp256k1.publicKeyVerify(letMeIn)) // true

  // Returning ecdh value is not necessary but is used in this demo for simplicity
  // Solver needs to _confirm_ an ecdh value against a set of precalculated known ones,
  // which can be done even after it's hashed or used e.g. for a stream/block cipher, based on the encrypted data
  solver.callback(secp256k1.ecdh(letMeIn, privateKey))

  // Btw we have those precomputed so we can actually use those sessions to lower suspicion, most -- instantly
}

// Now, we need a single valid (or another invalid) public key to recheck things against
// It can be anything, e.g. we can specify an 11th one, or create a valid one and use it
// We'll be able to confirm/restore and use the ecdh value for this session too upon privateKey extraction
const anyPublicKey = secp256k1.publicKeyCreate(randomBytes(32))
assert(secp256k1.publicKeyVerify(anyPublicKey)) // true (obviously)

// Full complexity of this exploit requires solver to perform ~ 2^35 ecdh value checks (for all 10 keys combined),
// which is ~ 1 TiB -- that can be done offline and does not require any further interaction with the target
// The exact speed of the comparison step depends on how the ecdh values are used, but is not very significant
// Direct non-indexed linear scan over all possible (precomputed) values takes <10 minutes on a MacBook Air
// Confirming against e.g. cipher output would be somewhat slower, but still definitely possible + also could be precomputed
const extracted = solver.stab(anyPublicKey, secp256k1.ecdh(anyPublicKey, privateKey))

console.log(`Extracted private key:  ${extracted.toString('hex')}`)
console.log(`Actual private key was: ${privateKey.toString('hex')}`)

assert(extracted.toString('hex') === privateKey.toString('hex'))

console.log('Oops')

Result:

Extracted private key:  e3370b1e6726a6ceaa51a2aacf419e25244e0cde08596780da021b238b74df3d
Actual private key was: e3370b1e6726a6ceaa51a2aacf419e25244e0cde08596780da021b238b74df3d
Oops
node example.js  178.80s user 13.59s system 74% cpu 4:17.01 total

Impact

Remote private key is extracted over 11 ECDH sessions

The attack is very low-cost, precompute took a few days on a single MacBook Air, and extraction takes ~10 minutes on the same MacBook Air

Also: * publicKeyVerify() misreports malicious public keys as valid * Same affects tweak extraction from publicKeyTweakMul result and other public key operations

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "secp256k1"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.0.0"
            },
            {
              "fixed": "5.0.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "5.0.0"
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "secp256k1"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0.0"
            },
            {
              "fixed": "4.0.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.8.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "secp256k1"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.8.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-48930"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-200",
      "CWE-354"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-10-21T17:28:26Z",
    "nvd_published_at": "2024-10-21T16:15:03Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nIn `elliptic`-based version, `loadUncompressedPublicKey` has a check that the public key is on the curve: https://github.com/cryptocoinjs/secp256k1-node/blob/6d3474b81d073cc9c8cc8cfadb580c84f8df5248/lib/elliptic.js#L37-L39\n\n`loadCompressedPublicKey` is, however, missing that check: https://github.com/cryptocoinjs/secp256k1-node/blob/6d3474b81d073cc9c8cc8cfadb580c84f8df5248/lib/elliptic.js#L17-L19\n\nThat allows the attacker to use public keys on low-cardinality curves to extract enough information to fully restore the private key from as little as 11 ECDH sessions, and very cheaply on compute power\n\nOther operations on public keys are also affected, including e.g. `publicKeyVerify()` incorrectly returning `true` on those invalid keys, and e.g. `publicKeyTweakMul()` also returning predictable outcomes allowing to restore the tweak \n\n### Details\n\nThe curve equation is `Y^2 = X^3 + 7`, and it restores `Y` from `X` in `loadCompressedPublicKey`, using `Y = sqrt(X^3 + 7)`, but when there are no valid `Y` values satisfying `Y^2 = X^3 + 7` for a given `X`, the same code calculates a solution for `-Y^2 = X^3 + 7`, and that solution also satisfies some other equation `Y^2 = X^3 + D`, where `D` is not equal to 7 and might be on a curve with factorizable cardinality, so `(X,Y)` might be a low-order point on that curve, lowering the number of possible ECDH output values to bruteforcable\n\nThose output values correspond to remainders which can be then combined with Chinese remainder theorem to restore the original value\n\nEndomorphism-based multiplication only slightly hinders restoration and does not affect the fact that the result is low-order\n\n10 different malicious X values could be chosen so that the overall extracted information is 238.4 bits out of 256 bit private key, and the rest is trivially bruteforcable with an additional 11th public key (which might be valid or not -- not significant)\n\nThe attacker does not need to _receive_ the ECDH value, they only need to be able to confirm it against a list of possible candidates, e.g. check if using it to decipher block/stream cipher would work -- and that could all be done locally on the attacker side\n\n### PoC\n\n#### Example public key\n\nThis key has order 39\nOne of the possible outcomes for it is a throw, 38 are predictable ECDH values\nKeys used in full attack have higher order (starting from ~20000), so are very unlikely to cause an error\n\n```js\nimport secp256k1 from \u0027secp256k1/elliptic.js\u0027\nimport { randomBytes } from \u0027crypto\u0027\n\nconst pub = Buffer.from(\u0027028ac57f9c6399282773c116ef21f7394890b6140aa6f25c181e9a91e2a9e3da45\u0027, \u0027hex\u0027)\n\nconst seen = new Set()\nfor (let i = 0; i \u003c 1000; i++) {\n  try {\n    seen.add(Buffer.from(secp256k1.ecdh(pub, randomBytes(32))).toString(\u0027hex\u0027))\n  } catch {\n    seen.add(\u0027failure also is an outcome\u0027)\n  }\n}\n\nconsole.log(seen.size) // 39\n```\n\n#### Full attack\nThis PoC doesn\u0027t list the exact public keys or the code for `solver.js` intentionally, but this exact code works, on arbitrary random private keys:\n\n```js\n// Only the elliptic version is affected, gyp one isn\u0027t\n// Node.js can use both, Web/RN/bundles always use the elliptic version\nimport secp256k1 from \u0027secp256k1/elliptic.js\u0027\n\nimport { randomBytes } from \u0027node:crypto\u0027\nimport assert from \u0027node:assert/strict\u0027\nimport { Solver } from \u0027./solver.js\u0027\n\nconst privateKey = randomBytes(32)\n\n// The full dataset is precomputed on a single MacBook Air in a few days and can be reused for any private key\nconst solver = new Solver\n\n// We need to run on 10 specially crafted public keys for this\n// Lower than 10 is possible but requires more compute\nfor (let i = 0; i \u003c 10; i++) {\n  const letMeIn = solver.ping() // this is a normal 33-byte Uint8Array, a 02/03-prefixed compressed public key\n  assert(letMeIn instanceof Uint8Array) // true\n  assert(secp256k1.publicKeyVerify(letMeIn)) // true\n\n  // Returning ecdh value is not necessary but is used in this demo for simplicity\n  // Solver needs to _confirm_ an ecdh value against a set of precalculated known ones,\n  // which can be done even after it\u0027s hashed or used e.g. for a stream/block cipher, based on the encrypted data\n  solver.callback(secp256k1.ecdh(letMeIn, privateKey))\n\n  // Btw we have those precomputed so we can actually use those sessions to lower suspicion, most -- instantly\n}\n\n// Now, we need a single valid (or another invalid) public key to recheck things against\n// It can be anything, e.g. we can specify an 11th one, or create a valid one and use it\n// We\u0027ll be able to confirm/restore and use the ecdh value for this session too upon privateKey extraction\nconst anyPublicKey = secp256k1.publicKeyCreate(randomBytes(32))\nassert(secp256k1.publicKeyVerify(anyPublicKey)) // true (obviously)\n\n// Full complexity of this exploit requires solver to perform ~ 2^35 ecdh value checks (for all 10 keys combined),\n// which is ~ 1 TiB -- that can be done offline and does not require any further interaction with the target\n// The exact speed of the comparison step depends on how the ecdh values are used, but is not very significant\n// Direct non-indexed linear scan over all possible (precomputed) values takes \u003c10 minutes on a MacBook Air\n// Confirming against e.g. cipher output would be somewhat slower, but still definitely possible + also could be precomputed\nconst extracted = solver.stab(anyPublicKey, secp256k1.ecdh(anyPublicKey, privateKey))\n\nconsole.log(`Extracted private key:  ${extracted.toString(\u0027hex\u0027)}`)\nconsole.log(`Actual private key was: ${privateKey.toString(\u0027hex\u0027)}`)\n\nassert(extracted.toString(\u0027hex\u0027) === privateKey.toString(\u0027hex\u0027))\n\nconsole.log(\u0027Oops\u0027)\n```\n\nResult:\n```console\nExtracted private key:  e3370b1e6726a6ceaa51a2aacf419e25244e0cde08596780da021b238b74df3d\nActual private key was: e3370b1e6726a6ceaa51a2aacf419e25244e0cde08596780da021b238b74df3d\nOops\nnode example.js  178.80s user 13.59s system 74% cpu 4:17.01 total\n```\n\n### Impact\n\nRemote private key is extracted over 11 ECDH sessions\n\nThe attack is very low-cost, precompute took a few days on a single MacBook Air, and extraction takes ~10 minutes on the same MacBook Air\n\nAlso:\n* `publicKeyVerify()` misreports malicious public keys as valid\n* Same affects tweak extraction from `publicKeyTweakMul` result and other public key operations",
  "id": "GHSA-584q-6j8j-r5pm",
  "modified": "2024-10-21T19:09:41Z",
  "published": "2024-10-21T17:28:26Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/cryptocoinjs/secp256k1-node/security/advisories/GHSA-584q-6j8j-r5pm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-48930"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cryptocoinjs/secp256k1-node/commit/8bd6446e000fa59df3cda0ae3e424300747ea5ed"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cryptocoinjs/secp256k1-node/commit/9a15fff274f83a6ec7f675f1121babcc0c42292f"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cryptocoinjs/secp256k1-node/commit/e256905ee649a7caacc251f7c964667195a52221"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/cryptocoinjs/secp256k1-node"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cryptocoinjs/secp256k1-node/blob/6d3474b81d073cc9c8cc8cfadb580c84f8df5248/lib/elliptic.js#L17-L19"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cryptocoinjs/secp256k1-node/blob/6d3474b81d073cc9c8cc8cfadb580c84f8df5248/lib/elliptic.js#L37-L39"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "secp256k1-node allows private key extraction over ECDH"
}

GHSA-5FJX-286J-PQ38

Vulnerability from github – Published: 2022-09-10 00:00 – Updated: 2022-09-15 00:00
VLAI
Details

Improper validation of integrity check vulnerability in Samsung Kies prior to version 2.6.4.22074 allows local attackers to delete arbitrary directory using directory junction.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-39845"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-09-09T15:15:00Z",
    "severity": "HIGH"
  },
  "details": "Improper validation of integrity check vulnerability in Samsung Kies prior to version 2.6.4.22074 allows local attackers to delete arbitrary directory using directory junction.",
  "id": "GHSA-5fjx-286j-pq38",
  "modified": "2022-09-15T00:00:19Z",
  "published": "2022-09-10T00:00:29Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-39845"
    },
    {
      "type": "WEB",
      "url": "https://security.samsungmobile.com/serviceWeb.smsb?year=2022\u0026month=09"
    },
    {
      "type": "WEB",
      "url": "https://security.samsungmobile.com/serviceWeb.smsb?year==2022\u0026month=09"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-5GP7-PF54-XC33

Vulnerability from github – Published: 2023-03-07 00:30 – Updated: 2023-03-13 18:30
VLAI
Details

The fix for CVE-2022-3437 included changing memcmp to be constant time and a workaround for a compiler bug by adding "!= 0" comparisons to the result of memcmp. When these patches were backported to the heimdal-7.7.1 and heimdal-7.8.0 branches (and possibly other branches) a logic inversion sneaked in causing the validation of message integrity codes in gssapi/arcfour to be inverted.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-45142"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-03-06T23:15:00Z",
    "severity": "HIGH"
  },
  "details": "The fix for CVE-2022-3437 included changing memcmp to be constant time and a workaround for a compiler bug by adding \"!= 0\" comparisons to the result of memcmp. When these patches were backported to the heimdal-7.7.1 and heimdal-7.8.0 branches (and possibly other branches) a logic inversion sneaked in causing the validation of message integrity codes in gssapi/arcfour to be inverted.",
  "id": "GHSA-5gp7-pf54-xc33",
  "modified": "2023-03-13T18:30:42Z",
  "published": "2023-03-07T00:30:24Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-45142"
    },
    {
      "type": "WEB",
      "url": "https://security.gentoo.org/glsa/202310-06"
    },
    {
      "type": "WEB",
      "url": "https://www.openwall.com/lists/oss-security/2023/02/08/1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-5XV8-FPCW-HXQ7

Vulnerability from github – Published: 2025-04-17 12:30 – Updated: 2025-04-17 12:30
VLAI
Details

The Forminator Forms – Contact Form, Payment Form & Custom Form Builder plugin for WordPress is vulnerable to Order Replay in all versions up to, and including, 1.42.0 via the 'handle_stripe_single' function due to insufficient validation on a user controlled key. This makes it possible for unauthenticated attackers to reuse a single Stripe PaymentIntent for multiple transactions. Only the first transaction is processed via Stripe, but the plugin sends a successful email message for each transaction, which may trick an administrator into fulfilling each order.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-3479"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-04-17T12:15:15Z",
    "severity": "MODERATE"
  },
  "details": "The Forminator Forms \u2013 Contact Form, Payment Form \u0026 Custom Form Builder plugin for WordPress is vulnerable to Order Replay in all versions up to, and including, 1.42.0 via the \u0027handle_stripe_single\u0027 function due to insufficient validation on a user controlled key. This makes it possible for unauthenticated attackers to reuse a single Stripe PaymentIntent for multiple transactions. Only the first transaction is processed via Stripe, but the plugin sends a successful email message for each transaction, which may trick an administrator into fulfilling each order.",
  "id": "GHSA-5xv8-fpcw-hxq7",
  "modified": "2025-04-17T12:30:33Z",
  "published": "2025-04-17T12:30:33Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-3479"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/forminator/tags/1.41.2/library/modules/custom-forms/front/front-action.php#L964"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/changeset/3274844"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/c873c04e-516e-41ee-a295-b8c5235abc1b?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-6282-8Q6J-R8Q2

Vulnerability from github – Published: 2025-02-17 06:30 – Updated: 2025-02-17 06:30
VLAI
Details

Improper Validation of Integrity Check Value vulnerability in TXOne Networks StellarProtect (Legacy Mode), StellarEnforce, and Safe Lock allows an attacker to escalate their privileges in the victim’s device. The attacker needs to hijack the DLL file in advance. This issue affects StellarProtect (Legacy Mode): before 3.2; StellarEnforce: before 3.2; Safe Lock: from 3.0.0 before 3.1.1076. *Note: StellarProtect (Legacy Mode) is the new name for StellarEnforce, they are the same product.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-47935"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-02-17T06:15:13Z",
    "severity": "MODERATE"
  },
  "details": "Improper Validation of Integrity Check Value vulnerability in TXOne Networks StellarProtect (Legacy Mode), StellarEnforce, and Safe Lock allows an attacker to escalate their privileges in the victim\u2019s device. The attacker needs to hijack the DLL file in advance.\nThis issue affects StellarProtect (Legacy Mode): before 3.2; StellarEnforce: before 3.2; Safe Lock: from 3.0.0 before 3.1.1076.\n*Note: StellarProtect (Legacy Mode) is the new name for StellarEnforce, they are the same product.",
  "id": "GHSA-6282-8q6j-r8q2",
  "modified": "2025-02-17T06:30:40Z",
  "published": "2025-02-17T06:30:40Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-47935"
    },
    {
      "type": "WEB",
      "url": "https://www.txone.com/psirt/advisories/cve-2024-47935"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-63G9-53GW-GH45

Vulnerability from github – Published: 2022-04-29 00:00 – Updated: 2022-05-10 00:00
VLAI
Details

The Zoom Client for Meetings for MacOS (Standard and for IT Admin) prior to version 5.9.6 failed to properly check the package version during the update process. This could lead to a malicious actor updating an unsuspecting user’s currently installed version to a less secure version.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-22781"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-354"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-04-28T15:15:00Z",
    "severity": "HIGH"
  },
  "details": "The Zoom Client for Meetings for MacOS (Standard and for IT Admin) prior to version 5.9.6 failed to properly check the package version during the update process. This could lead to a malicious actor updating an unsuspecting user\u2019s currently installed version to a less secure version.",
  "id": "GHSA-63g9-53gw-gh45",
  "modified": "2022-05-10T00:00:35Z",
  "published": "2022-04-29T00:00:24Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-22781"
    },
    {
      "type": "WEB",
      "url": "https://explore.zoom.us/en/trust/security/security-bulletin"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Implementation

Ensure that the checksums present in messages are properly checked in accordance with the protocol specification before they are parsed and used.

CAPEC-145: Checksum Spoofing

An adversary spoofs a checksum message for the purpose of making a payload appear to have a valid corresponding checksum. Checksums are used to verify message integrity. They consist of some value based on the value of the message they are protecting. Hash codes are a common checksum mechanism. Both the sender and recipient are able to compute the checksum based on the contents of the message. If the message contents change between the sender and recipient, the sender and recipient will compute different checksum values. Since the sender's checksum value is transmitted with the message, the recipient would know that a modification occurred. In checksum spoofing an adversary modifies the message body and then modifies the corresponding checksum so that the recipient's checksum calculation will match the checksum (created by the adversary) in the message. This would prevent the recipient from realizing that a change occurred.

CAPEC-463: Padding Oracle Crypto Attack

An adversary is able to efficiently decrypt data without knowing the decryption key if a target system leaks data on whether or not a padding error happened while decrypting the ciphertext. A target system that leaks this type of information becomes the padding oracle and an adversary is able to make use of that oracle to efficiently decrypt data without knowing the decryption key by issuing on average 128*b calls to the padding oracle (where b is the number of bytes in the ciphertext block). In addition to performing decryption, an adversary is also able to produce valid ciphertexts (i.e., perform encryption) by using the padding oracle, all without knowing the encryption key.

CAPEC-75: Manipulating Writeable Configuration Files

Generally these are manually edited files that are not in the preview of the system administrators, any ability on the attackers' behalf to modify these files, for example in a CVS repository, gives unauthorized access directly to the application, the same as authorized users.