Talos Vulnerability Report

TALOS-2025-2297

Canva Affinity EMF File EMR_FRAMERGN Type Confusion Vulnerability

March 17, 2026
CVE Number

CVE-2025-66342

SUMMARY

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.

CONFIRMED VULNERABLE VERSIONS

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

PRODUCT URLS

Affinity - https://www.affinity.studio/

CVSSv3 SCORE

7.8 - CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-843 - Access of Resource Using Incompatible Type (‘Type Confusion’)

DETAILS

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.

VENDOR RESPONSE

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)

TIMELINE

2026-01-27 - Vendor Disclosure
2026-03-17 - Vendor Patch Release
2026-03-17 - Public Release

Credit

Discovered by KPC of Cisco Talos.