Search: ge.call
2,492 threats
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| Medium | 6.1 | EPSS 0.1% | CVE-2026-10032Google @a2ui/web_core · Cross-site Scripting Medium6.1EPSS 0.1%CVE Database V5CVE-2026-10032 ### Summary The `openUrl` function in `@a2ui/web_core` passes an agent-controlled URL directly to `window.open()` without validating the URI scheme. A malicious agent can supply a `javascript:` URI as the `url` argument of a `Button` component's `functionCall` action. When the user clicks the rendered button, arbitrary JavaScript executes in the victim application's browser origin, constituting a stored/reflected XSS. No non-default configuration is required; the Basic Catalog is enabled by default. ### Details The vulnerability exists in the `openUrl` function implementation within the Basic Catalog of `@a2ui/web_core` (commit `23a003248abbf59da6c376ea64ace91d82d209ff`). **Sink** — `renderers/web_core/src/v0_9/basic_catalog/functions/basic_functions.ts:428-430`: ```ts export const OpenUrlImplementation = createFunctionImplementation(OpenUrlApi, args => { if (args.url && typeof window !== 'undefined' && window.open) { window.open(args.url, '_blank'); } }); ``` `window.open` is called unconditionally with the agent-supplied `args.url` value. No scheme allowlist or blocklist is applied. **Insufficient schema validation** — `renderers/web_core/src/v0_9/basic_catalog/functions/basic_functions_api.ts:453-458`: ```ts export const OpenUrlApi = { name: 'openUrl' as const, returnType: 'void' as const, schema: z.object({ url: z.preprocess(v => (v === undefined ? undefined : String(v)), z.string()), }), }; ``` The Zod schema only requires a `string`; `javascript:` URIs pass validation without any rejection. **Full source-to-sink data flow:** 1. `renderers/web_core/src/v0_9/basic_catalog/components/basic_components.ts:356` — `ButtonApi` accepts `action: ActionSchema` (entry point). 2. `renderers/web_core/src/v0_9/schema/common-types.ts:126-130` — `ActionSchema` permits `{ functionCall: FunctionCallSchema }`. 3. `renderers/web_core/src/v0_9/rendering/generic-binder.ts:243-255` — on click, bound action calls `resolveDeepSync` then `dispatchAction`. 4. `renderers/web_core/src/v0_9/rendering/data-context.ts:93-105` — `resolveDynamicValue` detects the `call` key and invokes the named function. 5. `renderers/web_core/src/v0_9/catalog/types.ts:177-186` — catalog invoker runs `fn.schema.parse(rawArgs)` then `fn.execute()`. 6. `renderers/web_core/src/v0_9/basic_catalog/functions/basic_functions_api.ts:453-458` — `OpenUrlApi` validates `url` as `z.string()` only (no scheme check). 7. `renderers/web_core/src/v0_9/basic_catalog/functions/basic_functions.ts:428-430` — **sink**: `window.open(args.url, '_blank')` executes the `javascript:` URI. **All three renderers implemented in the A2UI repository are affected:** - React: `renderers/react/src/v0_9/catalog/basic/components/Button.tsx:33` — `onClick={props.action}` - Lit: `renderers/lit/src/v0_9/catalogs/basic/components/Button.ts:112` — `@click=${() => props.action()}` - Angular: `renderers/angular/src/v0_9/catalog/basic/button.component.ts:103-110` — `handleClick()` → `dataContext.resolveAction` → `dispatchAction` Any other A2UI renderer which depends on `web_core` and uses its basic catalog implementation is also affected. ### Remediation The issue was fixed in [https://github.com/a2ui-project/a2ui/pull/1707](https://github.com/a2ui-project/a2ui/pull/1707) and released in web\_core version 0.10.2, by blocking URLs that do not use the HTTP or HTTPS schemes, or those that are invalid. Please fix this issue in your project by depending on a @a2ui/web\_core version equal or greater than 0.10.2. | CVE Database V5 | ||
| High | 8.7 | EPSS 0.5% | CVE-2026-68494FasterXML jackson-core · Unthrottled Resource Allocation High8.7EPSS 0.5%CVE Database V5CVE-2026-68494 The fix released in jackson-core 2.18.6 and 2.21.1 for CVE-2026-18401 (GHSA-72hv-8253-57qq, number length constraint bypass in the non-blocking parser) is incomplete. This record covers the remaining bypass. The earlier fix wired validateIntegerLength() into a new _setIntLength() helper and invoked it wherever the integer portion of a number is decided: a terminator byte arrives, a '.' or 'e'/'E' is seen, or input ends inside a fully buffered value. It was not invoked on the attacker-relevant path where the parser runs out of input while still inside the MINOR_NUMBER_INTEGER_DIGITS minor state and returns NOT_AVAILABLE to the caller. As a result, an attacker who streams JSON to a non-blocking parser in many small chunks, without ever sending a terminator byte, keeps the parser inside MINOR_NUMBER_INTEGER_DIGITS indefinitely. _textBuffer.expandCurrentSegment() grows the accumulator on every chunk while validateIntegerLength() is never called. The accumulator is bounded only by maxStringLength (20 MiB by default) rather than by maxNumberLength (1000 by default), an amplification of roughly 20,000x over the documented limit. Because Java char values occupy two bytes, a single connection can be driven to approximately 40 MiB of heap before the validator finally fires when the value completes. The equivalent fraction-path code is correct: _finishFloatFraction() calls _setFractLength() before its NOT_AVAILABLE return. The missing call affects the integer-digit paths in _startPositiveNumber(), _startNegativeNumber() and _finishNumberIntegralPart() in NonBlockingUtf8JsonParserBase. Impact: reactive frameworks such as Spring WebFlux/Reactor, Quarkus, Helidon and Vert.x feed inbound HTTP or gRPC bytes to the async parser as they arrive, which is precisely the chunked-feed shape required. Operators who set StreamReadConstraints.maxNumberLength expecting it to cap memory per number value do not get that guarantee; memory accumulates per concurrent connection and attacker-controlled concurrency can exhaust the JVM heap. The synchronous parsers (UTF8StreamJsonParser, ReaderBasedJsonParser) and the async parser operating on complete input are not affected. Exploitation requires only the ability to stream data to a parsing endpoint; no privileges or user interaction are needed. This issue affects com.fasterxml.jackson.core:jackson-core from version 2.15.0 through 2.18.7, and from 2.19.0 through 2.21.3, and tools.jackson.core:jackson-core from 3.0.0 through 3.1.3. Versions prior to 2.15.0 are not affected, because StreamReadConstraints -- which defines the maxNumberLength setting -- was first introduced in jackson-core 2.15.0, so no such constraint exists to be bypassed in earlier releases. Note that GHSA-r7wm-3cxj-wff9 states the affected 2.x range without a lower bound. The 2.22.x and 3.2.x release lines are not affected: those branches were created after the fix commit landed on 2026-05-21 and therefore contain it from their initial releases (2.22.0, tagged 2026-06-03, and 3.2.0, tagged 2026-06-08). | CVE Database V5 | ||
| Medium | – | EPSS 0.1% | CVE-2026-29111Red Hat Security Advisory: systemd security update MediumEPSS 0.1%GCVE DatabaseCVE-2026-29111 A moderate severity vulnerability (CVE-2026-29111) exists in systemd, the system and service manager for Linux. The flaw allows for arbitrary code execution or denial of service via malformed IPC API call data. This affects Red Hat Enterprise Linux 8.6 Extended Life Cycle Long Life and AUS variants. A security update addressing this issue is available from Red Hat. | GCVE Database | ||
| High | 8.7 | EPSS 0.4% | CVE-2026-62927Eclipse Milo · Incorrect Authorization High8.7EPSS 0.4%CVE Database V5CVE-2026-62927 CVE-2026-62927 is a high-severity authorization bypass vulnerability in Eclipse Milo versions 1.0.0 through 1.1.4. The Call service incorrectly dispatches mixed batches of method calls after authorization checks, allowing low-privileged or anonymous clients to execute methods that should be denied by batching them with allowed methods. | CVE Database V5 | ||
| Medium | 6.3 | EPSS 0.4% | Medium6.3EPSS 0.4%CVE Database V5CVE-2026-66883 Improper Handling of Case Sensitivity vulnerability in Erlang Ecosystem Foundation oidcc_plug (Oidcc.Plug.Authorize module) renders the user agent session binding inert, removing a defense in depth control against replay of a stolen session. This vulnerability is associated with program files lib/oidcc/plug/authorize.ex and lib/oidcc/plug/authorization_callback.ex, and program routines Oidcc.Plug.Authorize.call/2 and Oidcc.Plug.AuthorizationCallback.call/2. Oidcc.Plug.Authorize.call/2 reads the initiating client's user agent with get_req_header(conn, "User-Agent"). Plug lowercases incoming header names, but get_req_header/2 matches the supplied key exactly and performs no normalization of its own, so the mixed-case lookup always returns an empty list and nil is written into the session. On the callback side, Oidcc.Plug.AuthorizationCallback treats a stored nil user agent as nothing to compare and returns :ok without inspecting the request. The two behaviours combine so that the check passes unconditionally on every request, including for deployments that explicitly opted in with check_useragent: true, and an authorization callback can be completed from a different user agent than the one that initiated the flow without detection. The check fails open silently, with no error and no log entry, so a deployment cannot tell the binding is absent. The impact is limited to defense in depth. The inert check does not by itself allow an attacker to complete an authorization flow; it removes one layer that would otherwise hinder use of a stolen or leaked session, such as an exfiltrated session cookie replayed from a different client. The CSRF/state, nonce, and PKCE checks are unaffected and continue to function. Deployments that never enabled check_useragent are not affected in practice, since they never expected the binding. The corresponding lookup in Oidcc.Plug.AuthorizationCallback correctly uses the lowercase key and is not affected. This issue affects oidcc_plug: from 0.1.0-alpha.3 before 0.5.0. | CVE Database V5 | ||
| –Not rated | – | Cisco Talos Actor usage of AI is exploding. By analyzing artifacts left behind, Talos has created a detailed analysis of how we are seeing adversaries leverage the technology to include development, force multiplication, and vulnerability research. Based on the evidence Talos gathered, guardrails did not provide much protection, with most actors able to convince the models to comply despite the lack of sophisticated techniques or encoding. The pre-existing skill of the actor has a large impact on what they can accomplish with AI. Talos observed novice users able to create malicious capabilities, albeit with limited capabilities and success. Advanced users were able to build astonishing capabilities, pushing the models to create sophisticated and complex outputs. Artificial intelligence (AI) and associated language models are now ubiquitous and heavily used in both personal and professional contexts to streamline tasks and expand capabilities. With AI being used everywhere and by almost everyone, one of the biggest questions is how malicious actors are taking advantage. Fortunately, actors make mistakes and chatbots leave artifacts. Leveraging cloud-based AI models leaves behind a variety of artifacts, most notably a prompt log. These logs can take on a variety of shapes and sizes, but they are left on endpoints that are running various applications, such as Claude Code, CodeX, Cursor, or Gemini. Over the course of our research, we’ve collected a significant corpus of these files and can start discussing the ways we see bad actors leveraging these technologies. In conducting the research, three categories of activity emerged. One was using AI as a malicious software engineer, leveraging AI to write (in some cases) very sophisticated code with clear malicious intentions. Another was actors leveraging AI to scale criminal operations and campaigns. Finally, there were a lot of actors leveraging it for bug bounty or vulnerability research, rapidly accelerating their capabilities of discovery and disclosure. Each category demonstrates how threat actors are currently leveraging AI. Within each category is a wide disparity in sophistication based on the knowledge level of the actors involved. We tried to include use cases to cover the breadth of what we found. Takeaways and high-level findings With the recent disclosures from Hugging Face and OpenAI , it's clear the era of agentic attackers has effectively arrived. In that incident, the models were operating inside a sanctioned evaluation with safeguards deliberately relaxed — but they autonomously escaped their sandbox, found and chained real vulnerabilities, and compromised production infrastructure to reach their objective. The capabilities exist; the only missing ingredient is malicious intent, and it's a matter of time before threat actors supply it. For defenders, this is a wake-up call: Vulnerabilities will surface faster, exploitation will happen sooner, and the actors behind it won't need rest or downtime. As the case studies below show, the central challenge for guardrails right now is supporting legitimate dual-use work — red teaming and vulnerability research — without empowering malicious actors. One of the immediate takeaways is that guardrails are not functioning as expected. We did not encounter any sophisticated encoding or techniques designed to trick the models — most of the time it was a simple “I'm allowed to do this,” and the model complied. When guardrails did engage, they accomplished little. In one instance, we watched an actor abandon a censored model and pivot to an uncensored version, which completed the task without question. In another, a model pushed back on a distributed denial-of-service (DDoS) operator, but by that point the tooling had already been built. This wasn't specific to a single model or platform; it was across the board. The other big takeaway is that an actor's skill level largely determines how effectively AI can be leveraged and how much impact it u… | Cisco Talos | |||
| High | 7.8 | EPSS 0.2% | High7.8EPSS 0.2%GCVE DatabaseCVE-2026-64563 In the Linux kernel, the following vulnerability has been resolved: rhashtable: clear stale iter->p on table restart rhashtable_walk_start_check() has two restart paths when resuming a walk. When iter->walker.tbl is valid, it re-validates iter->p against the table and sets iter->p = NULL if the object is gone. When iter->walker.tbl is NULL (table was freed during resize), it resets slot and skip but forgets to clear iter->p. rhashtable_walk_next() then dereferences the stale iter->p, reading freed memory. This is a use-after-free. Any caller that does multi-fragment rhashtable walks across walk_stop/walk_start boundaries is affected. Concrete cases include netlink_diag (__netlink_diag_dump in net/netlink/diag.c) and TIPC (tipc_nl_sk_walk in net/tipc/socket.c). Crash stack (netlink_diag): BUG: KASAN: slab-use-after-free in rhashtable_walk_next+0x365/0x3c0 Read of size 8 at addr ffff88801a9d2438 (freed kmalloc-2k, offset 1080) Call Trace: rhashtable_walk_next+0x365/0x3c0 (lib/rhashtable.c:1016) __netlink_diag_dump+0x160/0x760 (net/netlink/diag.c:122) netlink_diag_dump+0xc2/0x240 netlink_dump+0x5bc/0x1270 netlink_recvmsg+0x7a3/0x980 sock_recvmsg+0x1bc/0x200 __sys_recvfrom+0x1d4/0x2c0 | GCVE Database | ||
| Critical | 9.1 | EPSS 2.0% | Critical9.1EPSS 2.0%GCVE Database OpenEMR versions through 8.2.0 contain a critical remote code execution vulnerability in the document category tree component. Authenticated administrators can inject PHP payloads into the categories database table by exploiting a flaw that allows altering the id column type to VARCHAR and inserting malicious code. This payload is executed via an unsanitized eval() call whenever the CategoryTree class is instantiated, including on pages accessible to unauthenticated or low-privilege users, resulting in command execution as the web server user. | GCVE Database | ||
| High | – | EPSS 0.5% | HighEPSS 0.5%GCVE DatabaseCVE-2026-67313 Red Hat has issued a security advisory for Red Hat Hardened Images RPMs including grafana13.1, addressing multiple vulnerabilities identified by CVE-2026-67313 through CVE-2026-67318. One notable vulnerability, CVE-2026-67313, involves an uncontrolled recursion in the axios library's formDataToJSON function, which can lead to a denial of service (DoS) by exhausting the JavaScript call stack. The advisory provides updated RPM packages to mitigate these issues. | GCVE Database | ||
| Medium | 4.8 | EPSS 0.1% | CVE-2026-18604textPlus Text Message and Call App · Improper Export of Android Application Components Medium4.8EPSS 0.1%CVE Database V5CVE-2026-18604 CVE-2026-18604 is a medium severity vulnerability in the textPlus Text Message and Call App for Android, versions 8.3.0 through 8.3.5. It involves improper export of the DialerActivity component, which can be exploited locally. Public exploit code is available, but no known in-the-wild exploitation has been reported. The vendor was notified early, but no patch information is provided. EPSS 0.1%Vulnerability | CVE Database V5 | ||
| High | 7.3 | EPSS 0.3% | CVE-2026-69097GitPython · Injection High7.3EPSS 0.3%CVE Database V5CVE-2026-69097 ### Summary In GitPython `<= 3.1.52`, the config writer neutralizes only CR, LF, and NUL in configuration **names**, but writes section names into the `[...]` header with no other escaping. A section/subsection name that contains `] [ "` closes the intended header and opens a second same-line section, injecting an arbitrary config directive — with no newline required. Because a submodule **name** is attacker-controlled data (it comes from a repository's `.gitmodules`, or from an application that lets a user name a submodule) and is written verbatim into the parent repository's trusted `.git/config`, an attacker can set `core.sshCommand` (or `alias.*`, `core.pager`, `core.fsmonitor`) and achieve remote code execution on the victim's next git operation. Likely **CWE-74 (Injection)**. This is a distinct variant of the injection addressed by GHSA-mv93-w799-cj2w / GHSA-v87r-6q3f-2j67: those fixed **newline** injection into config values/names (patched in 3.1.50); the `[r\n\x00]` guard added for them does not stop a **same-line** section break inside a name. ### Details The only guard applied to section/option names before writing is `_assure_config_name_safe`, which uses a regex that matches solely CR/LF/NUL: `git/config.py:75,897-899` (`GitPython 3.1.52`): ```python UNSAFE_CONFIG_CHARS_RE = re.compile(r"[\r\n\x00]") ... def _assure_config_name_safe(self, name: "cp._SectionName", label: str) -> None: if isinstance(name, str) and UNSAFE_CONFIG_CHARS_RE.search(name): raise ValueError("Git config %s names must not contain CR, LF, or NUL" % label) ``` The name is then serialized into the header with no escaping of `]`, `[`, `"`, space, `=` or `#`: `git/config.py:693`: ```python fp.write(("[%s]\n" % name).encode(defenc)) ``` For submodules the name is wrapped as `submodule "<name>"` (`git/objects/submodule/util.py:39`, `return f'submodule "{name}"'`), which supplies the balancing quote. A submodule named: ``` x"] [core] sshCommand=CMD # ``` therefore serializes to the header `[submodule "x"] [core] sshCommand=CMD #"]`. git parses everything after the first `]` on that line as a fresh section, yielding `core.sshCommand=CMD` (the trailing `#"]` is an inline comment). No CR/LF/NUL appears, so `_assure_config_name_safe` never fires. The attacker-controlled name reaches this sink through documented public entry points that write it into the parent repository's `.git/config`: - `Repo.create_submodule(name=<untrusted>, ...)` → `Submodule.add` → `git/objects/submodule/base.py:619` `writer.set_value(sm_section(name), "url", url)` — a single call, no hostile remote required. - `Repo.clone_from(<hostile url>)` + `repo.submodule_update(init=True)` → `git/objects/submodule/base.py:855` `writer.set_value(sm_section(self.name), "url", self.url)`, where `self.name` is read unvalidated from the cloned repo's `.gitmodules`. Asymmetry: the sibling class is blocked — a newline in a config **value**, e.g. `set_value("core", "editor", "x\n\tsshCommand=CMD")`, raises `ValueError`. The section-**name** bracket payload is not caught by the same guard. ### PoC Single self-contained script, run against the pinned release in an ephemeral environment. Non-destructive: the injected value is an inert marker, verified parse-only with `git config --get`; no ssh/fetch/push is run and nothing is executed. ```python #!/usr/bin/env python3 """Minimal PoC: git-config section-name injection in GitPython==3.1.52.""" from importlib.metadata import version import os, tempfile, subprocess import git print(f"# GitPython {version('GitPython')}") # version proof -- first line MARKER = "MARKER_9f3a" # inert; never executed tmp = tempfile.mkdtemp() env = {**os.environ, "HOME": tmp, "GIT_CONFIG_GLOBAL": os.path.join(tmp, "gc"), "GIT_CONFIG_SYSTEM": os.devnull, "GIT_AUTHOR_NAME": "a", "GIT_AUTHOR_EMAIL": "a@b.c", "GIT_COMMITTER_NAME": "a", "GIT_COMMITTER_EMAIL": "a@b.c"} def run(*a, cwd=None): return subprocess.run(a, cwd=cwd, env=env, capture_output=True, text=True) # A benign local repo used as the submodule url (a plain path, no network). src = os.path.join(tmp, "src"); os.makedirs(src) run("git", "init", "-q", src) open(os.path.join(src, "f"), "w").write("x") run("git", "add", "f", cwd=src); run("git", "commit", "-qm", "i", cwd=src) suburl = os.path.join(tmp, "sub.git"); run("git", "clone", "-q", "--bare", src, suburl) def parent_repo(): p = tempfile.mkdtemp(dir=tmp) run("git", "init", "-q", p) open(os.path.join(p, "r"), "w").write("x") run("git", "add", "r", cwd=p); run("git", "commit", "-qm", "i", cwd=p) return p def injected_sshcommand(parent): r = run("git", "config", "-f", os.path.join(parent, ".git", "config"), "--get", "core.sshCommand") return (r.returncode, r.stdout.strip()) benign = "docs" evil = f'x"] [core] sshCommand={MARKER} #' # closes the header, opens [core] p_control = parent_repo() git.Repo(p_co | CVE Database V5 | ||
| High | 8.3 | EPSS 0.5% | CVE-2026-69086siyuan · Path Traversal High8.3EPSS 0.5%CVE Database V5CVE-2026-69086 **CVE:** This vulnerability corresponds to [CVE-2026-69086](https://nvd.nist.gov/vuln/detail/CVE-2026-69086). ### Summary Four attribute-view read endpoints build a filesystem path from a caller-controlled `id`/`avID` and read it without confining the result to the attribute-view storage directory (`DataDir/storage/av/`). On the load (file-exists) code path there is no boundary check, so an `avID` containing `../` segments escapes `storage/av/` and causes the kernel to read a `.json` file elsewhere in the workspace. The endpoints require only `CheckAuth`, which the publish service's `RoleReader` token satisfies; when `Publish.Auth.Enable` is `false` the publish proxy uses the anonymous account, making the surface reachable with no credentials. ### Details Affected endpoints (all gated by `CheckAuth` only, no `CheckAdminRole`): - `POST /api/av/renderAttributeView` → `arg["id"]` - `POST /api/av/getAttributeViewKeysByID` → `arg["avID"]` - `POST /api/av/getAttributeViewKeys` → `arg["id"]` - `POST /api/av/getCurrentAttrViewImages` → `arg["id"]` In `model.RenderAttributeView` (`model/attribute_view_render.go`), the only identifier guard `ast.IsNodeIDPattern(avID)` sits **inside** the `if !filelock.IsExist(existPath)` (create) branch: ```go existPath = GetAttributeViewDataPath(avID) // path built from avID, no check if !filelock.IsExist(existPath) { // NOT-EXIST / CREATE branch if !createIfNotExist { return // NotFound } if !ast.IsNodeIDPattern(avID) { // <-- ONLY id guard, create branch only return ErrInvalidID } // ... create ... } attrView, err = av.ParseAttributeView(avID) // LOAD runs unconditionally ``` When the traversal `avID` resolves to a file that already exists, the `!filelock.IsExist(...)` condition is `false`, the entire block (including the line with `ast.IsNodeIDPattern`) is skipped, and control falls straight through to `av.ParseAttributeView(avID)`. That function rebuilds the path via `filepath.Join(DataDir, "storage", "av", avID+".json")` and calls `filelock.ReadFile` with no `filepath.Rel` / `IsSubPath` / `..` rejection: ```go // av.ParseAttributeView -> attributeViewDataPathByBox / GetAttributeViewDataPath avJSONPath = filepath.Join(DataDir, "storage", "av", avID+".json") // no boundary check // -> parseAttributeViewByPathInBox(avJSONPath, boxID) data, _ = filelock.ReadFile(avJSONPath) // SINK ``` `filepath.Join` cleans the path but does **not** reject `..` segments, so it provides no containment. The three `getAttributeView*` endpoints call `ParseAttributeView` with no create branch at all, so they never even reach the `ast.IsNodeIDPattern` check same defect, same auth tier. The root cause is that identifier validation is placed on a single code branch rather than confining the load to the AV base directory, so the load path reads a caller-controlled location. ### PoC **Precondition:** publish mode enabled (default port `6808`); reachable by a `RoleReader` publish token, or anonymously when `Publish.Auth.Enable` is `false`. A request to `/api/av/renderAttributeView` with an `id` composed of `../` path segments that resolves to an existing `.json` file outside `DataDir/storage/av/` causes that file to be read and parsed instead of being rejected, because the identifier validation is only reached on the not-exist/create branch. I have withheld the exact encoded `id` value from this draft to avoid publishing a live traversal against internet-exposed publish instances. I'm happy to provide the precise value and a screenshot privately in this thread on request. ### Impact An authenticated publish `RoleReader` or an anonymous client when publish auth is disabled can cause the kernel to read `.json` files outside the attribute-view directory. Because the loaded file is unmarshalled into the attribute-view structure, the reliable primitives are: 1. Disclosure of attribute-view (database) content from other scopes/notebooks the reader is not authorized to see. 2. A `.json`-path existence oracle for arbitrary workspace locations. Files not conforming to the AV schema are read but reflect little content, and the `.json` suffix is force-appended, so this is **not** a general arbitrary-file read. No admin role, CSRF token, or write permission is required. ### Suggested fix Validate `avID` with `ast.IsNodeIDPattern` before path construction on **all** branches (move it ahead of `FindAttributeViewPath` / `GetAttributeViewDataPath`), or preferably, so every caller inherits it confine at the sink: in `attributeViewDataPathByBox` / `GetAttributeViewDataPath`, compute the joined path and reject it unless `filepath.Rel(avBaseDir, cleaned)` stays within `avBaseDir` (no leading `..`). Sink-side confinement also covers the three `getAttributeView*` endpoints that never reach the create-branch guard. | CVE Database V5 | ||
| Critical | 9.9 | EPSS 1.6% | CVE-2026-69084siyuan · SQL Injection Critical9.9EPSS 1.6%CVE Database V5CVE-2026-69084 **CVE:** This vulnerability corresponds to [CVE-2026-69084](https://nvd.nist.gov/vuln/detail/CVE-2026-69084). ### Summary The `/api/search/searchEmbedBlock` endpoint passes a client-supplied SQL statement verbatim to the database with no validation. The endpoint is gated by `CheckAuth` only reachable by the publish RoleReader token, and by the anonymous account when `Publish.Auth.Enable` is `false`. The statement runs on the main read-write `siyuan.db` handle through a driver that executes stacked statements, with no single-statement or read-only guard. An unauthenticated request can therefore execute arbitrary SQL reading and writing content across all cleartext notebooks. Unlike SQL injection into a fixed query, this endpoint accepts a full SQL statement by design and simply fails to restrict who may call it or what the statement may do. ### Details Data flow verbatim, unvalidated: - `searchEmbedBlock` (`kernel/api/search.go`): `stmt := arg["stmt"].(string)` passed directly to `model.SearchEmbedBlock(stmt, …)`. No validation. - `SearchEmbedBlock` → `SearchEmbedBlockInBox` → `sql.SelectBlocksRawStmtNoParse(stmt, …)` → `selectBlocksRawStmt` → `query(stmt)`. - `query()` (`kernel/sql/database.go`) calls `db.Query(stmt)` on the global `siyuan.db` handle. **Missing guards.** The comparable endpoints enforce restrictions this one omits: - `/api/query/sql` runs `CheckSingleStatement` (all modes) and `CheckReadonlyStatement` (readonly mode) and is route-gated `CheckAuth + CheckAdminRole + CheckReadonly`. - `fullTextSearchBlock` rejects the SQL search method for non-admins (`if method == 2 && !IsAdminRoleContext(c)`). `searchEmbedBlock` has none of these, no statement check, no read-only check, no admin gate. **Route/auth tier.** `router.go`: `Handle("POST", "/api/search/searchEmbedBlock", model.CheckAuth, searchEmbedBlock)`, `CheckAuth` only. `CheckAuth` admits `RoleReader`, and the publish proxy forwards port-6808 traffic with a Reader JWT (anonymous account when publish auth is disabled). Anonymous/reader reachable. **Handle/stacking.** `query()` uses the global `siyuan.db` handle, the same read-write handle behind the accepted `searchDocs` finding. Driver is the vendored `88250/go-sqlite3` (mattn fork), whose connection `query` loops over `;`-separated statements, so stacked statements execute for their side effects. The DSN sets no `mode=ro` / `_query_only`, so the handle is read-write; `ATTACH` is available. **Post-hoc filter does not bound the statement.** `FilterEmbedBlocksByPublishAccess` runs on the returned slice *after* `query()` has executed. It filters rows; it cannot constrain what the statement did. Any write or `ATTACH` side effect has already occurred before the filter runs. It is not a security boundary for this sink. **Scope.** The main `blocks`/DB handle spans every opened cleartext notebook. Encrypted notebooks use separate per-box databases and are excluded. ### Impact An unauthenticated request (publish mode with auth disabled) or any publish `RoleReader` executes arbitrary SQL on the main read-write database. This permits cross-notebook read disclosure of document content, and via the read-write handle and statement stacking, modification of database content and `ATTACH`-reachable files. No admin role, CSRF token, or write permission through the normal API is required. Encrypted notebooks are not exposed. Code execution is not reachable in the default build (no `load_extension`). ### PoC Steps 1. Build the kernel image from pinned HEAD `docker build -f D:/bb/zitadel/chatto/siyuan/Dockerfile.poc -t siyuan-head D:/bb/zitadel/chatto/siyuan` 2. Run fresh, workspace mounted to the host ``` docker rm -f siyuan-poc 2>nul docker run -d --name siyuan-poc -p 6806:6806 -p 6808:6808 -v D:/bb/siyuan:/siyuan/workspace siyuan-head serve --accessAuthCode=1234567 --port=6806 ``` Confirm it booted (version string back, not Cobra help): ``` docker logs siyuan-poc curl -s http://127.0.0.1:6806/api/system/version ``` 3. Grab the admin API token from the host file. Use that value wherever TOKEN appears below (yours was g4wj3r04ntobe9m4). 4. Turn on the reader surface: publish on 6808, Basic Auth OFF `curl -s -X POST http://127.0.0.1:6806/api/setting/setPublish -H "Content-Type: application/json" -H "Authorization: Token TOKEN" -d "{\"enable\":true,\"port\":6808,\"auth\":{\"enable\":false,\"accounts\":[]}}"` Must return "data":{"port":6808,...} (non-zero port = bound OK). Port 6808, not 6806. 5. THE PROOF: anonymous reader on 6808, no token (the differential) Guarded sibling rejects reader SQL: `curl -i -X POST http://127.0.0.1:6808/api/search/fullTextSearchBlock -H "Content-Type: application/json" -d "{\"query\":\"SELECT * FROM blocks LIMIT 1\",\"method\":2}"` → -1 / "SQL search requires administrator privileges" searchEmbedBlock accepts the same reader SQL (no guard): `curl -i -X POST http://127.0.0.1:6808/api/search/searchEmbedBlock -H "Content-Type: application/json" -d "{\"embedB | CVE Database V5 | ||
| Critical | 9.2 | EPSS 0.4% | CVE-2026-68586siyuan · Missing Authorization Critical9.2EPSS 0.4%CVE Database V5CVE-2026-68586 **CVE:** This vulnerability corresponds to [CVE-2026-68586](https://nvd.nist.gov/vuln/detail/CVE-2026-68586). ### Summary The backlink API splits into list endpoints (which documents reference a block) and content endpoints (the rendered text of those referencing blocks). The list endpoints apply a publish-access filter, the content endpoints do not. As a result, `/api/ref/getBacklinkDoc` and `/api/ref/getBackmentionDoc` return the rendered DOM of blocks belonging to a publish-forbidden document to an anonymous reader, with no access check. Both content endpoints are gated by `CheckAuth` only, reachable by the publish `RoleReader` token and by the anonymous account when `Publish.Auth.Enable` is `false`. ### Details The asymmetry between the list and content sides is the tell that this is an oversight, not intended behavior: | Endpoint | Returns | Publish-access filter | Route | |---|---|---|---| | `getBacklink` | list (`*Path`) | `FilterPathsByPublishAccess` - present | `CheckAuth` | | `getBacklink2` | list (`*Path`) | `FilterPathsByPublishAccess` - present | `CheckAuth` | | `getBacklinkDoc` | rendered DOM | none | `CheckAuth` | | `getBackmentionDoc` | rendered DOM | none | `CheckAuth` | `model/backlink.go` contains no publish-access reference anywhere, and `Backlink.DOM` is the rendered HTML of the referencing blocks. `getBacklinkDoc(defID, refTreeID)` returns the rendered content of blocks in `refTreeID` - including a publish-forbidden, publish-disabled, or password-protected document with no access check. The filtered list siblings (`getBacklink`/`getBacklink2`) demonstrate that the publish boundary is meant to apply to this data; the content endpoints simply omit it. A reader is not limited to the filtered backlink list, they call `getBacklinkDoc` directly with any `refTreeID`. This also yields a reference-existence oracle: the response reveals whether the forbidden document `refTreeID` references the block `defID`. ### Proof of Concept Reproduced on a local instance (SiYuan running locally, publish mode enabled on port 6808, publish Basic Auth disabled). Setup: a publish-forbidden document `D` (`REFTREEID`) whose body contains the unique marker `SECRET_MARKER_77` and which references a block `DEFID` in a separate known document. **1. Mark the target document publish-forbidden (admin action, the boundary that should block reads):** ``` POST http://127.0.0.1:6806/api/filetree/setPublishAccess Authorization: Token <admin-token> {"id":"REFTREEID","visible":false,"password":"","disable":true} ``` **2. Baseline: the list endpoint correctly hides the forbidden doc from the reader (anonymous, port 6808):** ``` POST http://127.0.0.1:6808/api/ref/getBacklink2 {"id":"DEFID","k":"","mk":""} ``` The returned backlinks do not include the forbidden document `D`, the list side is filtered. **3. Disclosure: the content endpoint returns the forbidden doc's blocks anyway (anonymous, port 6808):** ``` POST http://127.0.0.1:6808/api/ref/getBacklinkDoc {"defID":"DEFID","refTreeID":"REFTREEID","keyword":""} ``` Returns HTTP 200; `data.backlinks[].dom` contains `SECRET_MARKER_77`, the rendered content of the publish-forbidden document, returned to an anonymous reader. `getBackmentionDoc` behaves identically for mention-type references. ### Impact An anonymous reader (publish mode with auth disabled) or any publish `RoleReader`, can read the rendered content of a publish-forbidden document's referencing blocks, defeating a boundary the administrator explicitly configured, and can determine whether a forbidden document references a given block (a reference-existence oracle). **Precondition (stated honestly):** the request requires `refTreeID` (the forbidden document's ID) and `defID` (a block it references). `defID` may be any published/known block, so if the forbidden document references any public content, `defID` is known and only `refTreeID` need be supplied. Block/document IDs for forbidden documents are also obtainable from other `CheckAuth`-only endpoints that lack the publish-access filter (reported separately). This endpoint alone does not enumerate arbitrary documents; it discloses content once an ID is known. Impact is confidentiality-only: content disclosure plus a reference-existence oracle, no modification. No admin role, CSRF token, or write permission is required. Encrypted notebooks are out of scope. ### Suggested fix Apply the same publish-access check the list siblings use. In `getBacklinkDoc`/`getBackmentionDoc`, filter each `Backlink` by its source document's box/path via `CheckPathAccessableByPublishIgnore` plus the publish-password cookie check consistent with `FilterPathsByPublishAccess` in `getBacklink`/`getBacklink2`. Any endpoint returning rendered block DOM should enforce the same publish boundary as the corresponding list endpoint. | CVE Database V5 | ||
| Critical | 9.3 | EPSS 0.3% | CVE-2026-68582vikunja · Insecure Direct Object Reference Critical9.3EPSS 0.3%CVE Database V5CVE-2026-68582 ## Summary The task-collection endpoint `GET /api/v1/projects/{project}/views/{view}/tasks` loads the requested project view straight from the URL path without verifying the caller is authorized for it. For a **link-share token**, the task query is correctly pinned to the share's own project, but the *view* is taken from the attacker-controlled path and never re-validated against the share. A holder of a share link to **any** project can therefore point the endpoint at any other tenant's kanban view and receive that view's bucket records — bucket titles plus the full `created_by` user object (username, name, id) — for every view in the instance. The same missing pre-authorization view load also yields a project/view-ID existence oracle (404 vs. non-404) usable by link shares and ordinary authenticated users alike. ## Details Root cause is in `TaskCollection.ReadAll` (`pkg/models/task_collection.go`). 1. The view is resolved from the URL params before any permission check: ```go // pkg/models/task_collection.go (ReadAll) if tf.ProjectViewID != 0 { view, err = GetProjectViewByIDAndProject(s, tf.ProjectViewID, tf.ProjectID) // (URL params) ... } ``` `GetProjectViewByIDAndProject` (`pkg/models/project_view.go`) filters only on `WHERE id = ? AND project_id = ?` — it performs no authorization. A valid `(project, view)` pair returns the view; an invalid pair returns `ErrProjectViewDoesNotExist` (HTTP 404). 2. For a link-share caller, the code pins the *task* scope to the token's own project but reuses the attacker-supplied `view`: ```go shareAuth, is := a.(*LinkSharing) if is { project, err := GetProjectSimpleByID(s, shareAuth.ProjectID) // token's project ... return getTaskOrTasksInBuckets(s, a, []*Project{project}, view, opts, filteringForBucket, tf.forceFlatTasks) // `view` is the foreign, attacker-controlled view — never validated against shareAuth.ProjectID } ``` 3. `getTaskOrTasksInBuckets` → `GetTasksInBucketsForView` (`pkg/models/kanban.go`) reads the buckets of that foreign view directly: ```go err = s.Where("project_view_id = ?", view.ID).OrderBy("position").Find(&buckets) ... users, err := getUsersOrLinkSharesFromIDs(s, userIDs) // resolves each bucket's created_by ``` Each returned `Bucket` serializes `CreatedBy *user.User` as `json:"created_by"` (`pkg/models/kanban.go`), exposing the creating user's username, name, and id. The normal (non-share) path is protected because it runs `getRelevantProjectsFromCollection`, which calls `project.CanRead` on the URL project and returns 403 before any bucket data is produced. Only the `LinkSharing` branch skips that gate, which is why the bucket disclosure is link-share-specific. `ReadAllWeb` (`pkg/web/handler/read_all.go`) performs no permission check of its own, so all authorization for this endpoint lives inside `ReadAll`. Scope of the leak (verified against fixtures): the *tasks* returned inside the buckets are still constrained to the share's own project (`getRawTasksForProjects` filters `tasks.project_id IN opts.projectIDs`, derived from the share's project). So victim task **contents do not leak**; what leaks is the foreign view's bucket structure and, critically, the `created_by` user identities of arbitrary buckets instance-wide. Introduced in v0.24.0 by the per-view kanban feature (`feat(views)!: return tasks in buckets by view`), which added the `views/{view}/tasks` endpoint and the foreign-view bucket load. The link-share branch predates it, but the two only combine into this bug from v0.24.0 onward. ## Impact A holder of a link-share token to any single project (link shares are designed to be handed out, often semi-publicly) can: - **Enumerate all project and view IDs instance-wide.** IDs are sequential auto-increment integers; an invalid `(project, view)` pair returns 404 while a valid one returns 200, giving a reliable existence oracle across all tenants. - **Disclose the `created_by` user of any kanban view's buckets** — username, display name, and user id. Because Vikunja auto-creates a default project with a Kanban view for every user, iterating view IDs enumerates usernames and user IDs for essentially every account on the instance. - **Disclose bucket titles** of every kanban view in the instance. This is a cross-tenant broken-object-level-authorization bypass. It does not disclose victim task contents through this path, but instance-wide username/user-id enumeration plus kanban structure disclosure is a meaningful PII and reconnaissance exposure that defeats the tenant isolation the permission model is meant to enforce. The ID-enumeration oracle additionally works for any ordinary authenticated user (invalid combo → 404 vs. inaccessible combo → 403), because the view is loaded before the `CanRead` check. ## Proof of Concept Prerequisites: link sharing enabled (default), a share link to any project (call it project A), and any second project B (e.g. another tenant's) with a kanban view V_B. 1. Au | CVE Database V5 | ||
| High | 8.7 | EPSS 0.4% | CVE-2026-67356ArcadeData arcadedb · Improper Privilege Management High8.7EPSS 0.4%CVE Database V5CVE-2026-67356 ArcadeDB before 26.7.3 binds the real LocalDatabase object into JavaScript trigger contexts with HostAccess.ALL, allowing schema-admins to call getSecurity().createUser() without permission checks. Attackers with UPDATE_SCHEMA permission can create triggers that execute JavaScript to create server-wide admin users, escalating privileges beyond their authorization level. | CVE Database V5 |
Page 45 of 141 · 4 duplicate CVE records merged