Search

Find a vulnerability

Search criteria

    1 vulnerability found for SmartBear Collaborator Server by same weakness class, same vendor, different product line, with shared code

    GCVE-1988-2026-0490

    Vulnerability from gna-1988 – Published: 2026-11-02 07:30 – Updated: 2026-11-02 07:30
    VLAI
    Title
    [0day-rubbish] SmartBear Collaborator Server 15.1.15101 authenticated DOORS/Simulink review-file upload zip-slip to anonymous webroot Groovy Server Page execution as uid 1001 (7.5)
    Summary
    0day Rubbish Research Team is publicly disclosing a vulnerability in SmartBear Collaborator Server 15.1.15101, the closed-source peer and technical code-review platform from SmartBear that runs as a Java web application on Apache Tomcat. One low-privilege authenticated account plants a Groovy Server Page in the Tomcat webroot through an archive-extraction path traversal, and any anonymous client - a crawler, a scanner, anyone - then executes it with an ordinary GET, yielding operating-system command execution as uid=1001(collab) inside the product's own JVM. Root was not reached, is not claimed, and no privilege escalation was attempted. Read the deployment-shape caveat first, because it decides whether this chain works at all and it is the reason the published headline carries Attack Complexity High. The only shipped artifact this research exercised was the vendor's official container image, and in that image used exactly as shipped THE CHAIN DOES NOT WORK. The image declares the webserver content directory as a VOLUME and the installer never creates that path, so the container runtime creates the mount point itself as drwxr-xr-x owned by root while the service runs as uid 1001; the first filesystem call of the whole feature, Files.createDirectories(destVersionDir.toPath()) at HtmlBaseFilesUploadService.java:77, fails with EACCES before any archive entry is read and no byte is ever written. That block cannot be worked around from inside the product, because setWebserver has exactly one call site, at startup, from the content-webserver context parameter declared at ROOT.xml:92 with override="false". The shape in which the chain does succeed is the native, non-container install, and that shape was never run on a real host: the claim that a native install leaves that directory owned by the service account is a labelled structural inference from the shipped archive, not a measurement. This advisory therefore does not claim that every deployment of this product is exploitable. Type and root cause. CWE-22, path traversal through archive entry names, with CWE-94 (code generation via the *.gsp template mapping), CWE-732, CWE-693, CWE-668 and CWE-916 contributing. The JSON-API command ReviewService.addDoorsFiles accepts a zip archive from any authenticated user and dispatches through ReviewServiceImpl.addZipFiles:969-1001 to the first-party extractor com.smartbear.ccollab.doors.DoorsFilesUploadService.upload. Across that extraction loop the only validation of an entry is that the entry object is not null (:73-75) and the only filter is the keyword list IGNORE_FILES_KEYWORDS = {"__MACOSX"} declared at :63 and applied at :79. The entry name is passed through a cosmetic square-bracket substitution at :77 - Strings.replaceSquareBracketsToRound, which exists to satisfy the downstream DOORS document parser and has nothing to do with paths - and is then concatenated into a destination at :78 with File entryDestination = new File(uploadContext.getDestVersionDir(), fileName); The two-argument File(File, String) constructor concatenates lexically: it does not canonicalise, does not resolve against the base and does not reject parent-directory segments. There is no normalize() call, no startsWith(destDir) containment test, no canonical-path comparison, no rejection of an absolute name, no rejection of a backslash-separated name, no extension allowlist or blocklist on this route, no cap on entry count or cumulative uncompressed size, and no per-object authorisation on the caller-supplied reviewId. Line :83 then creates whatever parent directories the attacker's name implies and line :84 opens the output stream, new FileOutputStream(entryDestination), which is the sink. An entry named ../../../../../webapps/ROOT/<name>.gsp escapes the per-review version directory and lands in the Tomcat webroot. A sibling implementation shares the identical defect and the identical parent class: com.smartbear.ccollab.matlab.SimulinkFilesUploadService.copyFilesFromZip at :186-203 resolves destDir.resolve(zipEntry.getName()).toFile() at :188 with no normalize(), no startsWith(destDir) and no .. rejection, and is reachable from ReviewService.addSimulinkFiles. Its checkArchive at :157-161 constrains only the first entry, which must be named exactly webview.html, and then ignores the rest - a format assertion, not a containment control. One root cause with two code instances is reported here as a single finding; the Simulink instance was never exercised end to end and carries two further gates, so its practical exploitability is strictly weaker and is claimed on source reading only. A restricted-file-pattern check that genuinely exists lives only in the sibling servlet VersionContentUploadServlet:90-93, on the JSON-API-free route, and it validates the version's already-existing paths rather than names inside the archive. The destination geometry is what makes a relative traversal practical instead of theoretical. The shared parent fixes the base: HtmlBaseFilesUploadService builds webServerFolder as <mode>/<reviewId>/<zip name without extension> at :70-71, joins it to SystemGlobals.getWebserver() at :74, and SystemGlobals.java:130 declares that value as the relative string "collaborator-webserver", so it resolves against the JVM working directory, measured as /usr/local/ccollab_server/tomcat. The complete destination is therefore /usr/local/ccollab_server/tomcat/collaborator-webserver/<mode>/<reviewId>/ <zipbase>/ver<N> Every segment is fixed by product logic or returned to the attacker, so the required climb is a deterministic function the attacker can compute: depth = 4 + n, where n is the number of path segments in the declared zip name after stripping .zip, and the constant 4 counts ver<N>, the mode segment, the review identifier and the webserver directory-name segment. Two independent measurements agree with it at two different values of n - five segments for a flat zip name, six for a zip name of the form <dir>/<name>.zip, both markers executing anonymously. Depth must be exact in both directions, and overshooting is not a safety margin: POSIX clamps ".." at the filesystem root, so too many segments turn the target into the absolute path /webapps/ROOT/<name>.gsp and the mandatory pre-write Files.createDirectories at :83 then fails with EACCES with nothing written, while undershooting lands silently inside the content tree, is served behind the authenticated /webserver/* prefix where an anonymous client receives 401, and leaves an attacker file on disk. The execution half is first-party configuration. The ROOT webapp's own web.xml:271-278 maps *.gsp to the upstream groovy.servlet.TemplateServlet on the anonymous surface, so a plain unauthenticated GET of the planted path compiles the page in memory and evaluates it. That is what converts a post-authentication arbitrary file write into code execution triggered by anyone, and it is why the write side and the trigger side sit on opposite sides of the authentication boundary: the party who plants the file and the party who runs it need not be the same. Confirmation, and what was deliberately not reproduced. The chain is self-verifying rather than interpretive: the planted template runs a single read-only identity command and echoes its output into the anonymous response body, together with a Generated by Groovy TemplateServlet timing comment that proves evaluation rather than static serving. The observed identity string was verbatim uid=1001(collab) gid=1001(collab) groups=1001(collab), with an empty effective capability set. The strongest result came from an independently rebuilt container with a different random marker tag, a different non-administrator account and a freshly created review; the reference implementation was then run end to end twice more against a writable-mount instance, so the finding rests on four mutually independent execution records, three of which used values that could not have been carried over from an earlier run. What was deliberately not reproduced: no reverse shell, no persistence, no scanning, no brute force, no mass traversal, no deletion of anything on the target and no write outside the single marker file. The marker template is left in place rather than removed by the tool, because removing it requires container or host access the tool has no business holding, and an explicit manual cleanup instruction is printed instead. Per-run marker tokens, session ticket values and container identities are withheld from the published advisory as artefacts of one execution on one host: tickets are 30-day credentials and were logged out at teardown. Scoring. The published headline is 7.5 High, CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H, recomputed from first principles with the CVSS 3.1 round-up-to-tenth rule: ISS = 1 - (0.44 * 0.44 * 0.44) = 0.914816; Impact at Scope Unchanged = 6.42 * 0.914816 = 5.87311872; Exploitability = 8.22 * 0.85 * 0.44 * 0.62 * 0.85 = 1.62014556; base = min(7.49326428, 10) = 7.49326428, rounded up to 7.5. Attack Complexity is High on the headline not because the traversal is subtle - it is not, the depth is deterministic, there is no race and there is no state to gather - but because success depends on a condition the attacker neither controls nor can verify from the product: that the upload tree is writable by the service uid. On the one shipped artifact actually exercised, the official container image used exactly as shipped, that condition is false, and on the shape where it is believed to hold it was never observed. Rating exploitability Low on the strength of an installer that was never run would let the headline rest on the one deployment shape that was never tested while the shape that was tested forbids the chain. This is the honest rating, not a pessimistic one: the chain is complete and deterministic wherever the precondition holds and the severity band does not move. One conditional reading is published beside it, labelled as conditional: 8.8 High, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Exploitability = 8.22 * 0.85 * 0.77 * 0.62 * 0.85 = 2.83525473, Impact 5.87311872, base = min(8.70837345, 10) = 8.70837345, rounded up to 8.8. It applies to installations in which the upload tree is writable by the service uid: the native install shape, and any container deployment where that volume was created with service-account ownership or chowned during deployment automation. The argument for Low there is real and runs like this: :77 creates the destination tree itself, on the line before the first archive entry is read, so the precondition is implied by the usability of the attacked feature - any installation in which DOORS review-file upload can return success is an installation in which that tree is already writable by uid 1001, and an attacker who can call addDoorsFiles and get anything other than a permission-derived InternalError is already in the exploitable shape. It is not the headline because those shapes were argued from the archive rather than run. Both readings are High, and neither says this is remotely exploitable without an account. The blocked shape is not handled as an Environmental metric adjustment, because Environmental describes the scorer's own deployment and would leave the base score looking unconditional. A rejected reading is recorded here with a correction to our own arithmetic, so that nobody inherits it. A Scope-Changed candidate - PR:L, S:C and all three impact metrics High, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - was carried during analysis and is rejected on the merits: the write and the evaluation happen in the same JVM, the same ROOT web application and the same uid 1001, over directories that account already owns, so no resource under a different security authority is affected; that an anonymous client can pull the trigger is a fact about who pulls it, which Attack Vector and User Interaction already price. The strongest case for Chan
    Severity
    No CVSS data available.
    Assigner
    VULNARCHIVE GNA GNA-1988
    GNA scorecard E 38/100 over 556 records in the last 180 days details

    {
      "containers": {
        "cna": {
          "affected": [
            {
              "product": "SmartBear Collaborator Server",
              "vendor": "same weakness class, same vendor, different product line, with shared code",
              "versions": [
                {
                  "status": "affected",
                  "version": "unknown"
                }
              ]
            }
          ],
          "credits": [
            {
              "lang": "en",
              "type": "finder",
              "value": "disclosure via Fulldisclosure"
            }
          ],
          "descriptions": [
            {
              "lang": "en",
              "value": "0day Rubbish Research Team is publicly disclosing a vulnerability in SmartBear\nCollaborator Server 15.1.15101, the closed-source peer and technical code-review\nplatform from SmartBear that runs as a Java web application on Apache Tomcat. One\nlow-privilege authenticated account plants a Groovy Server Page in the Tomcat\nwebroot through an archive-extraction path traversal, and any anonymous client -\na crawler, a scanner, anyone - then executes it with an ordinary GET, yielding\noperating-system command execution as uid=1001(collab) inside the product\u0027s own\nJVM. Root was not reached, is not claimed, and no privilege escalation was\nattempted.\n\nRead the deployment-shape caveat first, because it decides whether this chain\nworks at all and it is the reason the published headline carries Attack\nComplexity High. The only shipped artifact this research exercised was the\nvendor\u0027s official container image, and in that image used exactly as shipped THE\nCHAIN DOES NOT WORK. The image declares the webserver content directory as a\nVOLUME and the installer never creates that path, so the container runtime\ncreates the mount point itself as drwxr-xr-x owned by root while the service runs\nas uid 1001; the first filesystem call of the whole feature,\nFiles.createDirectories(destVersionDir.toPath()) at\nHtmlBaseFilesUploadService.java:77, fails with EACCES before any archive entry is\nread and no byte is ever written. That block cannot be worked around from inside\nthe product, because setWebserver has exactly one call site, at startup, from the\ncontent-webserver context parameter declared at ROOT.xml:92 with\noverride=\"false\". The shape in which the chain does succeed is the native,\nnon-container install, and that shape was never run on a real host: the claim\nthat a native install leaves that directory owned by the service account is a\nlabelled structural inference from the shipped archive, not a measurement. This\nadvisory therefore does not claim that every deployment of this product is\nexploitable.\n\nType and root cause. CWE-22, path traversal through archive entry names, with\nCWE-94 (code generation via the *.gsp template mapping), CWE-732, CWE-693,\nCWE-668 and CWE-916 contributing. The JSON-API command\nReviewService.addDoorsFiles accepts a zip archive from any authenticated user\nand dispatches through ReviewServiceImpl.addZipFiles:969-1001 to the first-party\nextractor com.smartbear.ccollab.doors.DoorsFilesUploadService.upload. Across that\nextraction loop the only validation of an entry is that the entry object is not\nnull (:73-75) and the only filter is the keyword list\nIGNORE_FILES_KEYWORDS = {\"__MACOSX\"} declared at :63 and applied at :79. The\nentry name is passed through a cosmetic square-bracket substitution at :77 -\nStrings.replaceSquareBracketsToRound, which exists to satisfy the downstream\nDOORS document parser and has nothing to do with paths - and is then concatenated\ninto a destination at :78 with\n\n    File entryDestination = new File(uploadContext.getDestVersionDir(), fileName);\n\nThe two-argument File(File, String) constructor concatenates lexically: it does\nnot canonicalise, does not resolve against the base and does not reject\nparent-directory segments. There is no normalize() call, no startsWith(destDir)\ncontainment test, no canonical-path comparison, no rejection of an absolute name,\nno rejection of a backslash-separated name, no extension allowlist or blocklist\non this route, no cap on entry count or cumulative uncompressed size, and no\nper-object authorisation on the caller-supplied reviewId. Line :83 then creates\nwhatever parent directories the attacker\u0027s name implies and line :84 opens the\noutput stream, new FileOutputStream(entryDestination), which is the sink. An\nentry named ../../../../../webapps/ROOT/\u003cname\u003e.gsp escapes the per-review version\ndirectory and lands in the Tomcat webroot.\n\nA sibling implementation shares the identical defect and the identical parent\nclass: com.smartbear.ccollab.matlab.SimulinkFilesUploadService.copyFilesFromZip\nat :186-203 resolves destDir.resolve(zipEntry.getName()).toFile() at :188 with\nno normalize(), no startsWith(destDir) and no .. rejection, and is reachable from\nReviewService.addSimulinkFiles. Its checkArchive at :157-161 constrains only the\nfirst entry, which must be named exactly webview.html, and then ignores the rest\n- a format assertion, not a containment control. One root cause with two code\ninstances is reported here as a single finding; the Simulink instance was never\nexercised end to end and carries two further gates, so its practical\nexploitability is strictly weaker and is claimed on source reading only. A\nrestricted-file-pattern check that genuinely exists lives only in the sibling\nservlet VersionContentUploadServlet:90-93, on the JSON-API-free route, and it\nvalidates the version\u0027s already-existing paths rather than names inside the\narchive.\n\nThe destination geometry is what makes a relative traversal practical instead of\ntheoretical. The shared parent fixes the base: HtmlBaseFilesUploadService builds\nwebServerFolder as \u003cmode\u003e/\u003creviewId\u003e/\u003czip name without extension\u003e at :70-71,\njoins it to SystemGlobals.getWebserver() at :74, and\nSystemGlobals.java:130 declares that value as the relative string\n\"collaborator-webserver\", so it resolves against the JVM working directory,\nmeasured as /usr/local/ccollab_server/tomcat. The complete destination is\ntherefore\n\n    /usr/local/ccollab_server/tomcat/collaborator-webserver/\u003cmode\u003e/\u003creviewId\u003e/\n        \u003czipbase\u003e/ver\u003cN\u003e\n\nEvery segment is fixed by product logic or returned to the attacker, so the\nrequired climb is a deterministic function the attacker can compute: depth = 4 +\nn, where n is the number of path segments in the declared zip name after\nstripping .zip, and the constant 4 counts ver\u003cN\u003e, the mode segment, the review\nidentifier and the webserver directory-name segment. Two independent\nmeasurements agree with it at two different values of n - five segments for a\nflat zip name, six for a zip name of the form \u003cdir\u003e/\u003cname\u003e.zip, both markers\nexecuting anonymously. Depth must be exact in both directions, and overshooting\nis not a safety margin: POSIX clamps \"..\" at the filesystem root, so too many\nsegments turn the target into the absolute path /webapps/ROOT/\u003cname\u003e.gsp and the\nmandatory pre-write Files.createDirectories at :83 then fails with EACCES with\nnothing written, while undershooting lands silently inside the content tree, is\nserved behind the authenticated /webserver/* prefix where an anonymous client\nreceives 401, and leaves an attacker file on disk.\n\nThe execution half is first-party configuration. The ROOT webapp\u0027s own\nweb.xml:271-278 maps *.gsp to the upstream groovy.servlet.TemplateServlet on the\nanonymous surface, so a plain unauthenticated GET of the planted path compiles\nthe page in memory and evaluates it. That is what converts a\npost-authentication arbitrary file write into code execution triggered by\nanyone, and it is why the write side and the trigger side sit on opposite sides\nof the authentication boundary: the party who plants the file and the party who\nruns it need not be the same.\n\nConfirmation, and what was deliberately not reproduced. The chain is\nself-verifying rather than interpretive: the planted template runs a single\nread-only identity command and echoes its output into the anonymous response\nbody, together with a Generated by Groovy TemplateServlet timing comment that\nproves evaluation rather than static serving. The observed identity string was\nverbatim uid=1001(collab) gid=1001(collab) groups=1001(collab), with an empty\neffective capability set. The strongest result came from an independently\nrebuilt container with a different random marker tag, a different\nnon-administrator account and a freshly created review; the reference\nimplementation was then run end to end twice more against a writable-mount\ninstance, so the finding rests on four mutually independent execution records,\nthree of which used values that could not have been carried over from an earlier\nrun. What was deliberately not reproduced: no reverse shell, no persistence, no\nscanning, no brute force, no mass traversal, no deletion of anything on the\ntarget and no write outside the single marker file. The marker template is left\nin place rather than removed by the tool, because removing it requires container\nor host access the tool has no business holding, and an explicit manual cleanup\ninstruction is printed instead. Per-run marker tokens, session ticket values and\ncontainer identities are withheld from the published advisory as artefacts of one\nexecution on one host: tickets are 30-day credentials and were logged out at\nteardown.\n\nScoring. The published headline is 7.5 High,\nCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H, recomputed from first principles\nwith the CVSS 3.1 round-up-to-tenth rule: ISS = 1 - (0.44 * 0.44 * 0.44) =\n0.914816; Impact at Scope Unchanged = 6.42 * 0.914816 = 5.87311872;\nExploitability = 8.22 * 0.85 * 0.44 * 0.62 * 0.85 = 1.62014556; base =\nmin(7.49326428, 10) = 7.49326428, rounded up to 7.5. Attack Complexity is High\non the headline not because the traversal is subtle - it is not, the depth is\ndeterministic, there is no race and there is no state to gather - but because\nsuccess depends on a condition the attacker neither controls nor can verify from\nthe product: that the upload tree is writable by the service uid. On the one\nshipped artifact actually exercised, the official container image used exactly as\nshipped, that condition is false, and on the shape where it is believed to hold\nit was never observed. Rating exploitability Low on the strength of an installer\nthat was never run would let the headline rest on the one deployment shape that\nwas never tested while the shape that was tested forbids the chain. This is the\nhonest rating, not a pessimistic one: the chain is complete and deterministic\nwherever the precondition holds and the severity band does not move.\n\nOne conditional reading is published beside it, labelled as conditional: 8.8\nHigh, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Exploitability = 8.22 *\n0.85 * 0.77 * 0.62 * 0.85 = 2.83525473, Impact 5.87311872, base =\nmin(8.70837345, 10) = 8.70837345, rounded up to 8.8. It applies to\ninstallations in which the upload tree is writable by the service uid: the\nnative install shape, and any container deployment where that volume was created\nwith service-account ownership or chowned during deployment automation. The\nargument for Low there is real and runs like this: :77 creates the destination\ntree itself, on the line before the first archive entry is read, so the\nprecondition is implied by the usability of the attacked feature - any\ninstallation in which DOORS review-file upload can return success is an\ninstallation in which that tree is already writable by uid 1001, and an attacker\nwho can call addDoorsFiles and get anything other than a permission-derived\nInternalError is already in the exploitable shape. It is not the headline\nbecause those shapes were argued from the archive rather than run. Both readings\nare High, and neither says this is remotely exploitable without an account. The\nblocked shape is not handled as an Environmental metric adjustment, because\nEnvironmental describes the scorer\u0027s own deployment and would leave the base\nscore looking unconditional.\n\nA rejected reading is recorded here with a correction to our own arithmetic, so\nthat nobody inherits it. A Scope-Changed candidate - PR:L, S:C and all three\nimpact metrics High, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - was carried\nduring analysis and is rejected on the merits: the write and the evaluation\nhappen in the same JVM, the same ROOT web application and the same uid 1001, over\ndirectories that account already owns, so no resource under a different security\nauthority is affected; that an anonymous client can pull the trigger is a fact\nabout who pulls it, which Attack Vector and User Interaction already price. The\nstrongest case for Chan"
            }
          ],
          "problemTypes": [
            {
              "descriptions": [
                {
                  "cweId": "CWE-22",
                  "description": "CWE-22",
                  "lang": "en",
                  "type": "CWE"
                },
                {
                  "cweId": "CWE-668",
                  "description": "CWE-668",
                  "lang": "en",
                  "type": "CWE"
                },
                {
                  "cweId": "CWE-693",
                  "description": "CWE-693",
                  "lang": "en",
                  "type": "CWE"
                },
                {
                  "cweId": "CWE-732",
                  "description": "CWE-732",
                  "lang": "en",
                  "type": "CWE"
                },
                {
                  "cweId": "CWE-916",
                  "description": "CWE-916",
                  "lang": "en",
                  "type": "CWE"
                },
                {
                  "cweId": "CWE-94",
                  "description": "CWE-94",
                  "lang": "en",
                  "type": "CWE"
                }
              ]
            }
          ],
          "providerMetadata": {
            "dateUpdated": "2026-11-02T07:30:03Z",
            "orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
            "shortName": "VULNARCHIVE"
          },
          "references": [
            {
              "tags": [
                "technical-description",
                "exploit"
              ],
              "url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Oct/19"
            },
            {
              "tags": [
                "technical-description"
              ],
              "url": "https://seclists.org/fulldisclosure/2026/Oct/19"
            },
            {
              "url": "https://0day-rubbish.com"
            },
            {
              "url": "https://0day-rubbish.com/blog/smartbear-collaborator-doors-upload-zip-slip-webroot-gsp-rce"
            },
            {
              "url": "https://github.com/Exploit-Garbage/0day-Rubbish"
            },
            {
              "url": "https://nmap.org/mailman/listinfo/fulldisclosure"
            },
            {
              "url": "https://seclists.org/fulldisclosure/"
            }
          ],
          "source": {
            "defect": [
              "https://seclists.org/fulldisclosure/2026/Oct/19"
            ],
            "discovery": "EXTERNAL"
          },
          "title": "[0day-rubbish] SmartBear Collaborator Server 15.1.15101 authenticated DOORS/Simulink review-file upload zip-slip to anonymous webroot Groovy Server Page execution as uid 1001 (7.5)",
          "x_gcve": [
            {
              "recordType": "advisory",
              "relationships": [],
              "vulnId": "GCVE-1988-2026-0490",
              "x_vulnarchive": {
                "archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Oct/19",
                "automated": true,
                "contentSha256": "fa2934455827d2e9656fe0eb8d368db9afc71b32d23fc4c64080535e17c0e875",
                "evidenceScore": 11,
                "messageId": "",
                "originalUrl": "https://seclists.org/fulldisclosure/2026/Oct/19",
                "policy": "vulnarchive-1",
                "sourceFormat": "text/html",
                "sourcePublishedAt": "2026-10-13T02:22:32Z"
              }
            }
          ]
        }
      },
      "cveMetadata": {
        "assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
        "assignerShortName": "VULNARCHIVE",
        "datePublished": "2026-11-02T07:30:03Z",
        "dateUpdated": "2026-11-02T07:30:03Z",
        "state": "PUBLISHED",
        "vulnId": "GCVE-1988-2026-0490"
      },
      "dataType": "CVE_RECORD",
      "dataVersion": "5.2"
    }