CVE-2025-66342
A type confusion vulnerability exists in the EMF functionality of Canva Affinity. A specially crafted EMF file can trigger this vulnerability, which can lead to memory corruption and result in arbitrary code execution.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Canva Affinity 3.0.1.3808
Affinity - https://www.affinity.studio/
7.8 - CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-843 - Access of Resource Using Incompatible Type (‘Type Confusion’)
Affinity is a professional and versatile suite of creative applications designed for graphic design, photo editing, and desktop publishing. It provides a fast, streamlined experience with powerful tools to create illustrations, edit images, and design print or digital layouts. The suite is widely regarded as a capable and affordable alternative the software like Adobe Creative Cloud.
Affinity applications support the EMF file format, and this vulnerability is associated with how EMF files are processed.
An EMF (Enhanced Metafile Format) file stores images in a device-independent form. It begins with a header (EMR_HEADER) that contains information about the structure and contents of the metafile. The structure of the EMR_HEADER is as follows:
Offset Size Name
------ ---- --------------------------------------
0x00 0x04 recordType (0x00000001 )
0x04 0x04 recordSize
0x08 0x10 bounds
0x18 0x10 frame
0x28 0x04 recordSignature (0x464D4520)
0x2C 0x04 version
0x30 0x04 sizeInBytes
0x34 0x04 numOfRecords
0x38 0x02 Handles
0x3A 0x02 Reserved
Please note that the structure of EMR_HEADER shown is not complete; it only includes the relevant fields.
For the EMR_HEADER record, the recordType must be 0x00000001. The recordSize indicates the total size of the header record in bytes. The recordSignature field defines the record signature, which must have the value 0x464D4520 (FME ). The sizeInBytes field specifies the size of the metafile in bytes. The numOfRecords indicates the total number of records present in the metafile, including the EMR_HEADER
This vulnerability is associated with the record type EMR_FRAMERGN.
The EMR_FRAMERGN record draws a border using the specified brush. The structure of the EMR_FRAMERGN record is as follows:
Offset Size Name
----- ---------- --------------------------------------
0x00 0x04 recordType (0x00000048 )
0x04 0x04 recordSize
0x08 0x10 Bounds
0x18 0x04 RgnDataSize (n)
0x1C 0x04 ihBrush
0x20 0x04 Width
0x24 0x04 Height
0x28 n RgnData
For the EMR_FRAMERGN record, the recordType value must be 0x00000048. The vulnerable field is ihBrush. The ihBrush field specifies the index of the brush object in the EMF object table. Note that the brush object is created by EMR_CREATEBRUSHINDIRECT.
The structure of the EMR_CREATEBRUSHINDIRECT record is as follows:
Offset Size Name
----- ---------- --------------------------------------
0x00 0x04 recordType (0x00000027 )
0x04 0x04 recordSize
0x08 0x04 ihBrush
0x0C 0x0C LogBrush
Please note that the structure of EMR_CREATEBRUSHINDIRECT shown is not complete; it only includes the relevant fields.
This vulnerability occurs when the value of ihBrush in the EMR_FRAMERGN record does not match the value of ihBrush in the EMR_CREATEBRUSHINDIRECT record.
In this case, the value of ihBrush is 0x01 for the EMR_CREATEBRUSHINDIRECT record, as shown below:
27 00 00 00 18 00 00 00 01 00 00 00 00 00 00 00
FF 00 00 00 00 00 00 00
It means the brush object is stored at index 0x01 in the EMF object table. However, the value of ihBrush is 0x33 in the EMR_FRAMERGN record, as shown below:
48 00 00 00 58 00 00 00 32 00 00 00 32 00 00 00
C7 00 00 00 C7 00 00 00 30 00 00 00 33 00 00 00
0A 00 00 00 0A 00 00 00 20 00 00 00 01 00 00 00
01 00 00 00 10 00 00 00 32 00 00 00 32 00 00 00
C8 00 00 00 C8 00 00 00 32 00 00 00 32 00 00 00
C8 00 00 00 C8 00 00 00
When 0x33 is used as the index to retrieve the brush object from the EMF object table, it returns an arbitrary object because the actual brush object is stored at index 1. When this arbitrary object is used as a brush object without proper validation, a type confusion vulnerability occurs. This behavior can be observed while debugging the application with pageheap enabled.
0:032> g
libpersona!Emf::EmfLoader::LoadDocument+0x4edd7:
00007ffa`4ef1cf57 400fb6d7 movzx edx,dil
0:032> r
rax=000001d9ae242e80 rbx=000001d9a884efd0 rcx=00000020aa9ff390
rdx=0000000000000033 rsi=00000020aa9ff390 rdi=0000000000000033
rip=00007ffa4ef1cf57 rsp=00000020aa9fedc0 rbp=00000020aa9feec0
r8=0000000000000000 r9=00000000000000e0 r10=00007ffafa1d0000
r11=00007ffafa1e1469 r12=00007ffa4ef1fe80 r13=000001d9ae242e80
r14=0000000000000000 r15=00000020aa9ff390
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
libpersona!Emf::EmfLoader::LoadDocument+0x4edd7:
00007ffa`4ef1cf57 400fb6d7 movzx edx,dil; <--------------------------- (1)
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4eddb:
00007ffa`4ef1cf5b 48b825232284e49cf2cb mov rax,0CBF29CE484222325h
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ede5:
00007ffa`4ef1cf65 4833d0 xor rdx,rax
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ede8:
00007ffa`4ef1cf68 49b8b301000000010000 mov r8,100000001B3h
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4edf2:
00007ffa`4ef1cf72 490fafd0 imul rdx,r8
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4edf6:
00007ffa`4ef1cf76 0fb68d29010000 movzx ecx,byte ptr [rbp+129h] ss:00000020`aa9fefe9=00
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4edfd:
00007ffa`4ef1cf7d 4833d1 xor rdx,rcx
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee00:
00007ffa`4ef1cf80 490fafd0 imul rdx,r8
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee04:
00007ffa`4ef1cf84 0fb68d2a010000 movzx ecx,byte ptr [rbp+12Ah] ss:00000020`aa9fefea=00
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee0b:
00007ffa`4ef1cf8b 4833d1 xor rdx,rcx
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee0e:
00007ffa`4ef1cf8e 490fafd0 imul rdx,r8
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee12:
00007ffa`4ef1cf92 0fb6852b010000 movzx eax,byte ptr [rbp+12Bh] ss:00000020`aa9fefeb=00
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee19:
00007ffa`4ef1cf99 4833d0 xor rdx,rax
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee1c:
00007ffa`4ef1cf9c 490fafd0 imul rdx,r8
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee20:
00007ffa`4ef1cfa0 49239798000000 and rdx,qword ptr [r15+98h] ds:00000020`aa9ff428=0000000000000007
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee27:
00007ffa`4ef1cfa7 4803d2 add rdx,rdx
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee2a:
00007ffa`4ef1cfaa 498b8780000000 mov rax,qword ptr [r15+80h] ds:00000020`aa9ff410=000001d99132ef80
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee31:
00007ffa`4ef1cfb1 488b5cd008 mov rbx,qword ptr [rax+rdx*8+8] ds:000001d9`9132efe8=000001d98f518fc0
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee36:
00007ffa`4ef1cfb6 498b4f70 mov rcx,qword ptr [r15+70h] ds:00000020`aa9ff400=000001d98f518fc0
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee3a:
00007ffa`4ef1cfba 483bd9 cmp rbx,rcx
0:032> r
rax=000001d99132ef80 rbx=000001d98f518fc0 rcx=000001d98f518fc0
rdx=000000000000000c rsi=00000020aa9ff390 rdi=0000000000000033
rip=00007ffa4ef1cfba rsp=00000020aa9fedc0 rbp=00000020aa9feec0
r8=00000100000001b3 r9=00000000000000e0 r10=00007ffafa1d0000
r11=00007ffafa1e1469 r12=00007ffa4ef1fe80 r13=000001d9ae242e80
r14=0000000000000000 r15=00000020aa9ff390
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
libpersona!Emf::EmfLoader::LoadDocument+0x4ee3a:
00007ffa`4ef1cfba 483bd9 cmp rbx,rcx ; <--------------------------- (2)
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee3d:
00007ffa`4ef1cfbd 7419 je libpersona!Emf::EmfLoader::LoadDocument+0x4ee58 (00007ffa`4ef1cfd8) [br=1]
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee58:
00007ffa`4ef1cfd8 498bde mov rbx,r14
0:032> dq 000001d98f518fc0
000001d9`8f518fc0 000001d9`91fc4fc0 000001d9`91fc4fc0
000001d9`8f518fd0 c0c0c0c0`c0c0c0c0 c0c0c0c0`c0c0c0c0
000001d9`8f518fe0 c0c0c0c0`c0c0c0c0 c0c0c0c0`c0c0c0c0
000001d9`8f518ff0 c0c0c0c0`c0c0c0c0 d0d0d0d0`d0d0d0d0
000001d9`8f519000 ????????`???????? ????????`????????
000001d9`8f519010 ????????`???????? ????????`????????
000001d9`8f519020 ????????`???????? ????????`????????
000001d9`8f519030 ????????`???????? ????????`????????
At (1), the rdi register contains the ihBrush value from the EMR_FRAMERGN record. It is used as an index to read an object. The result of this object lookup is stored in the rcx register at (2). This is the vulnerable object.
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee5b:
00007ffa`4ef1cfdb 4885db test rbx,rbx
0:032> p
libpersona!Emf::EmfLoader::LoadDocument+0x4ee5e:
00007ffa`4ef1cfde 480f44d9 cmove rbx,rcx
0:032> p;r
rax=000001d99132ef80 rbx=000001d98f518fc0 rcx=000001d98f518fc0
rdx=000000000000000c rsi=00000020aa9ff390 rdi=0000000000000033
rip=00007ffa4ef1cfe2 rsp=00000020aa9fedc0 rbp=00000020aa9feec0
r8=00000100000001b3 r9=00000000000000e0 r10=00007ffafa1d0000
r11=00007ffafa1e1469 r12=00007ffa4ef1fe80 r13=000001d9ae242e80
r14=0000000000000000 r15=00000020aa9ff390
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
libpersona!Emf::EmfLoader::LoadDocument+0x4ee62:
00007ffa`4ef1cfe2 488b7b18 mov rdi,qword ptr [rbx+18h] ds:000001d9`8f518fd8=c0c0c0c0c0c0c0c0 ; <----------- (3)
0:032> p;r
rax=000001d99132ef80 rbx=000001d98f518fc0 rcx=000001d98f518fc0
rdx=000000000000000c rsi=00000020aa9ff390 rdi=c0c0c0c0c0c0c0c0
rip=00007ffa4ef1cfe6 rsp=00000020aa9fedc0 rbp=00000020aa9feec0
r8=00000100000001b3 r9=00000000000000e0 r10=00007ffafa1d0000
r11=00007ffafa1e1469 r12=00007ffa4ef1fe80 r13=000001d9ae242e80
r14=0000000000000000 r15=00000020aa9ff390
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
libpersona!Emf::EmfLoader::LoadDocument+0x4ee66:
00007ffa`4ef1cfe6 4885ff test rdi,rdi
0:032> p;r
rax=000001d99132ef80 rbx=000001d98f518fc0 rcx=000001d98f518fc0
rdx=000000000000000c rsi=00000020aa9ff390 rdi=c0c0c0c0c0c0c0c0
rip=00007ffa4ef1cfe9 rsp=00000020aa9fedc0 rbp=00000020aa9feec0
r8=00000100000001b3 r9=00000000000000e0 r10=00007ffafa1d0000
r11=00007ffafa1e1469 r12=00007ffa4ef1fe80 r13=000001d9ae242e80
r14=0000000000000000 r15=00000020aa9ff390
iopl=0 nv up ei ng nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000286
libpersona!Emf::EmfLoader::LoadDocument+0x4ee69:
00007ffa`4ef1cfe9 0f84b2050000 je libpersona!Emf::EmfLoader::LoadDocument+0x4f421 (00007ffa`4ef1d5a1) [br=0]
0:032> p;r
rax=000001d99132ef80 rbx=000001d98f518fc0 rcx=000001d98f518fc0
rdx=000000000000000c rsi=00000020aa9ff390 rdi=c0c0c0c0c0c0c0c0
rip=00007ffa4ef1cfef rsp=00000020aa9fedc0 rbp=00000020aa9feec0
r8=00000100000001b3 r9=00000000000000e0 r10=00007ffafa1d0000
r11=00007ffafa1e1469 r12=00007ffa4ef1fe80 r13=000001d9ae242e80
r14=0000000000000000 r15=00000020aa9ff390
iopl=0 nv up ei ng nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000286
libpersona!Emf::EmfLoader::LoadDocument+0x4ee6f:
00007ffa`4ef1cfef 48897c2438 mov qword ptr [rsp+38h],rdi ss:00000020`aa9fedf8=0000000000000000
Later, at (3), the vulnerable object is used as a brush object. In this case, the field at offset 0x18 of the vulnerable object is not initialized. When this uninitialized value is used as a pointer, a crash occurs.
0:032> g
(1318.1270): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
libpersona!Emf::EmfLoader::LoadDocument+0x4ee74:
00007ffa`4ef1cff4 488b4708 mov rax,qword ptr [rdi+8] ds:c0c0c0c0`c0c0c0c8=????????????????
0:032> u
libpersona!Emf::EmfLoader::LoadDocument+0x4ee74:
00007ffa`4ef1cff4 488b4708 mov rax,qword ptr [rdi+8]
00007ffa`4ef1cff8 48634804 movsxd rcx,dword ptr [rax+4]
00007ffa`4ef1cffc 488b4c3910 mov rcx,qword ptr [rcx+rdi+10h]
00007ffa`4ef1d001 ff1521677d0e call qword ptr [libpersona!WhiteBalanceAdjustmentRasterNode::__GetDefaultSerialisation+0x11bc6a8 (00007ffa`5d6f3728)]
00007ffa`4ef1d007 90 nop
00007ffa`4ef1d008 488b7710 mov rsi,qword ptr [rdi+10h]
00007ffa`4ef1d00c 4889742448 mov qword ptr [rsp+48h],rsi
00007ffa`4ef1d011 4885f6 test rsi,rsi
0:032> kb
# RetAddr : Args to Child : Call Site
00 00007ffa`4ef14882 : 00000000`00000000 000001d9`00000033 000001d9`a884efd0 000001d6`f11200b0 : libpersona!Emf::EmfLoader::LoadDocument+0x4ee74
01 00007ffa`4ef20bbb : 000001d9`91960fd0 000001d9`a884efd0 000001d9`8e997fd0 000001d9`a884efd0 : libpersona!Emf::EmfLoader::LoadDocument+0x46702
02 00007ffa`4ef1fe9c : 00000020`aa9ff390 00000000`000000b0 00000000`00000000 00000000`00000000 : libpersona!Emf::EmfLoader::LoadDocument+0x52a3b
03 00007ffa`faf0e73f : 00000000`000000b0 000001d9`bf8e4d20 000001d6`af810000 000001d6`af810000 : libpersona!Emf::EmfLoader::LoadDocument+0x51d1c
04 00007ffa`fc56d432 : 000001d9`82646fd0 00000020`00000000 000001d9`82646fd0 00000000`00000000 : gdi32full!bInternalPlayEMF+0x250bf
05 00007ffa`4ef215ce : 00000000`00000000 00000020`aa9ff3f0 00000020`aa9ff670 000001d9`8da4af90 : GDI32!EnumEnhMetaFileStub+0x52
06 00007ffa`4eecdb56 : 00000020`aa9ff390 00000020`aa9ff320 00000000`00000000 00007ffa`fd881910 : libpersona!Emf::EmfLoader::LoadDocument+0x5344e
07 00007ffa`4eece041 : 000001d9`8da4af90 000001d9`bf8e4d20 000001d9`8da4af90 00000020`aa9ff670 : libpersona!Emf::EmfLoader::LoadDocument+0x86
08 00007ffa`4eece2ab : 00000020`aa9ff708 000001d9`8da4af90 00000020`aa9ff670 00000000`00000000 : libpersona!Emf::EmfLoader::LoadDocument+0x101
09 00007ffa`4eece124 : 000001d9`f6551740 00000020`aa9ff708 00000020`aa9ff6d8 00000020`aa9ff751 : libpersona!Emf::EmfLoader::LoadDocument+0x12b
0a 00007ffa`4ec83a94 : 000001d9`c314af60 000001d9`f6551740 00000020`aa9ff7b0 00000020`aa9ffa78 : libpersona!Emf::EmfLoader::LoadDocument+0x94
0b 00007ffa`4ec5088f : 000001d9`f6551740 00000000`00000000 00000000`00000000 00000000`ffffff00 : libpersona!DocumentController::TryLoadEMF+0xc4
0c 00007ffa`4ec4eacc : 00000000`00000000 000001d9`00000001 00000000`00000000 00000000`00000000 : libpersona!DocumentController::LoadDocumentI+0xfaf
0d 00007ffa`51283602 : 000001d9`c5310690 00000000`00000000 000001d9`e43daf70 00000000`00000000 : libpersona!DocumentController::LoadDocument+0x8c
0e 00007ffa`52a96cea : 000001d9`c53106c8 000001d9`b03bef00 00007ffa`af8c2800 00000000`00000000 : libpersona!LoadDocumentCommand::Do+0x252
0f 00007ffa`af2464cf : 00000000`00000000 000001d9`e43daf70 00000000`00000000 000001d9`a4476fe0 : libpersona!PersonaController::StaticDoCommand+0x3a
10 00007ffa`af49f47f : 000001d9`80fa8fd0 00000000`00000481 00000000`00000000 000001d9`a8c3ef90 : libkernel!Kernel::InSerialiserPropertyDataStream::LoadValues+0xb787f
11 00007ffa`fcc17374 : 00007ffa`af8c2800 00000000`00000000 00000000`00000000 00000000`00000000 : libkernel!Kernel::InSerialiserPropertyDataStream::LoadValues+0x31082f
12 00007ffa`fd87cc91 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
13 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
0:032> lmDvm libpersona
Browse full module list
start end module name
00007ffa`49180000 00007ffa`60abb000 libpersona (export symbols) C:\Program Files\WindowsApps\Canva.Affinity_3.0.1.3808_x64__8a0j1tnjnt4a4\App\libpersona.dll
Loaded symbol image file: C:\Program Files\WindowsApps\Canva.Affinity_3.0.1.3808_x64__8a0j1tnjnt4a4\App\libpersona.dll
Image path: C:\Program Files\WindowsApps\Canva.Affinity_3.0.1.3808_x64__8a0j1tnjnt4a4\App\libpersona.dll
Image name: libpersona.dll
Browse all global symbols functions data Symbol Reload
Timestamp: Mon Nov 3 07:34:40 2025 (6908CB90)
CheckSum: 17822078
ImageSize: 1793B000
Mapping Form: Loaded
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
Information from resource tables:
Depending on the memory layout of the process, it may be possible to gain arbitrary read and write access, which could ultimately be abused to achieve arbitrary code execution.
See security bulletin on trust.canva.com with the vulnerability details and vulnerable versions. (URL to advisory: https://trust.canva.com/?tcuUid=1f728b0d-17f3-4c9c-97e9-6662b769eb62)
2026-01-27 - Vendor Disclosure
2026-03-17 - Vendor Patch Release
2026-03-17 - Public Release
Discovered by KPC of Cisco Talos.