{"answers":{"affected":"1 open source package ship an affected version, including jwt.","exploited":"There is no known exploitation of HSEC-2026-0010 in the wild and no public exploit code.","fix":"Upgrade jwt to 0.12.0 or later.","what":"HSEC-2026-0010 is a vulnerability in jwt, published on 29 Sep 2026. An attacker can exploit it over the internet without logging in, with no action from the victim."},"fix_prompt":"Check this codebase for HSEC-2026-0010 and fix it if it is affected.\n\nWhat it is: HSEC-2026-0010 is a vulnerability in jwt, published on 29 Sep 2026. An attacker can exploit it over the internet without logging in, with no action from the victim.\nExploitation: There is no known exploitation of HSEC-2026-0010 in the wild and no public exploit code.\n\nAffected packages and fixed versions:\n- jwt (Hackage): affected from 0.1.0; fixed in 0.12.0\n\nTask:\n1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.\n2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.\n3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.\n4. Run the tests and summarise what changed and why.\n5. If nothing in the project is affected, say so and change nothing.\n\nReference: https://insights.sbomify.com/HSEC-2026-0010/ (Markdown: https://insights.sbomify.com/HSEC-2026-0010/index.md)","id":"HSEC-2026-0010","markdown":"https://insights.sbomify.com/HSEC-2026-0010/index.md","name":"HSEC-2026-0010","record":{"aliases":[],"analysis":{"component_type":"library","fix_type":"upgrade","impacts":["security_bypass"],"network_reachable":"yes","non_default_config":false,"product_category":"Haskell JWT library","requires_auth":"none","summary":"The Haskell jwt library incorrectly parses fractional JWT expiration times, allowing expired tokens to be accepted as valid.","user_interaction":"not_required","vuln_class":"security_feature_bypass"},"analysis_generated_by":"qwen3.8-flash-next","assigner":null,"cpe":[],"cvss":{"score":null,"severity":null,"source":null,"vector":null,"version":null},"cwes":[],"description":"# Improper parsing of fractional `NumericDate` from JWT `exp` claims\n\nSince its [initial commit][], package jwt uses [`Data.Scientific.coefficient`][scientific] to extract the fractional mantissa in a way that improperly *discards the exponent*. This can lead to incorrect parsing of the `exp` claim in JWT payload body.\n\nPoC:\n\n```haskell\ncabal repl --build-depends jwt==0.11.0\n\nimport Web.JWT\n:set -XOverloadedStrings\n\nlet signer = VerifyHMACSecret \"dummy-signing-symmetric-hmac-key.not-so-secret\"\nlet exploit = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkhvbmVzdCBKb2UiLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNzkwMTY2Nzg2LCJleHAiOjE3OTAxNzAzODYuMDAwMX0.xQyl3rBYtVTxPL_VXSawSSmZkuF4MzOkzwdQGJFjE2o\"\n-- {\n--   \"sub\": \"1234567890\",\n--   \"name\": \"Honest Joe\",\n--   \"admin\": true,\n--   \"iat\": 1790166786,\n--   \"exp\": 1790170386.0001\n-- }\nλλ ➔ Just whoops = Web.JWT.decodeAndVerifySignature signer exploit\nλ\nλλ ➔ whoops\nVerified (JOSEHeader {typ = Just \"JWT\", cty = Nothing, alg = Just HS256, kid = Nothing}) (JWTClaimsSet {iss = Nothing, sub = Just 1234567890, aud = Nothing, exp = Just (NumericDate 17901703860001), nbf = Nothing, iat = Just (NumericDate 1790166786), jti = Nothing, unregisteredClaims = ClaimsMap {unClaimsMap = fromList [(\"admin\",Bool True),(\"name\",String \"Honest Joe\")]}}) (Signature \"xQyl3rBYtVTxPL_VXSawSSmZkuF4MzOkzwdQGJFjE2o\")\nλ\nλλ ➔ fmap secondsSinceEpoch . Web.JWT.iat . claims $ whoops\nJust 1790166786s\nλ\nλλ ➔ fmap secondsSinceEpoch . Web.JWT.exp . claims $ whoops\nJust 17901703860001s\n```\n\nThe encoded claim `exp = 1790170386.0001` is:\n1. Explicitly allowed by RFC 7519 [section 2][rfc-2] to contain fractional part (*\"... non-integer values can be represented.\"*);\n2. Decodes correctly as `2026-09-23T12:33:06.0001` (including in JS implementations on jwt.io \u0026 token.dev);\n3. Decodes incorrectly as `569252-05-30T12:40:01`  (== posix epoch `17901703860001`) by the `jwt` library.\n   ```\n   \u003e\u003e\u003e import Data.Time.Format.ISO8601\n   \u003e\u003e\u003e import Data.Time.Clock.POSIX\n   \u003e\u003e\u003e\n   \u003e\u003e\u003e iso8601Show $ posixSecondsToUTCTime 1790166786\n   \"2026-09-23T12:33:06Z\"\n   \u003e\u003e\u003e\n   \u003e\u003e\u003e iso8601Show $ posixSecondsToUTCTime 17901703860001\n   \"569252-05-30T12:40:01Z\"\n   ```\nThis happens because jwt's `instance FromJSON NumericDate` only extracts the parsed `coefficient` while ignoring [`base10Exponent`][scientific], which in this case becomes negative non-zero.\n\nSince the standard `exp` claim carries credential expiration time:\n\n\u003e  ### [4.1.4][rfc-4.1.4].  \"exp\" (Expiration Time) Claim\n\u003e \n\u003e    The \"exp\" (expiration time) claim identifies the expiration time on\n\u003e    or after which the JWT MUST NOT be accepted for processing.  The\n\u003e    processing of the \"exp\" claim requires that the current date/time\n\u003e    MUST be before the expiration date/time listed in the \"exp\" claim.\n\n— this parsing mistake of dropping the exponent can have security-relevant consequences, should an attacker be able to forge JWTs with fractional expiry dates and get them fed into software that uses the `jwt` library for consuming JWTs.\n\n[initial commit]: https://github.com/puffnfresh/haskell-jwt/commit/76567342c71f62f3f7554da8987579d90e532209\n[rfc-2]: https://www.rfc-editor.org/info/rfc7519/#section-2\n[rfc-4.1.4]: https://www.rfc-editor.org/info/rfc7519/#section-4.1.4\n[scientific]: https://hackage-content.haskell.org/package/scientific-0.3.8.1/docs/Data-Scientific.html#g:2","ecosystems":["Hackage"],"exploits":{"exploitdb":null,"first_seen":null,"github_poc":null,"max_poc_stars":null,"metasploit":null,"nuclei":null,"refs":[],"tier":null},"has_fix":true,"headline":"Improper parsing of fractional NumericDate from JWT exp claims","id":"HSEC-2026-0010","indexable":true,"kev":null,"kind":"advisory","links":{"ecosystem":null,"product":null,"products":[],"type":"security_feature_bypass","year":"2026"},"n_packages":1,"n_references":null,"packages":[{"ecosystem":"Hackage","fixed":["0.12.0"],"introduced":["0.1.0"],"last_affected":[],"package":"jwt","purl":"pkg:hackage/jwt","source":"HSEC-2026-0010"}],"products":null,"published":"2026-09-29","related":[],"sources":[{"class":"open","licence":"CC0 1.0","name":"Haskell Security Response Team","prefix":"HSEC"}],"ssvc":{"automatable":null,"exploitation":null,"technical_impact":null},"state":null,"updated":null,"vendors":null},"summary":"The Haskell jwt library incorrectly parses fractional JWT expiration times, allowing expired tokens to be accepted as valid.","url":"https://insights.sbomify.com/HSEC-2026-0010/"}