Skip to content

Commit 8310661

Browse files
authored
Move supported definitions to separate file (#34)
1 parent 895262d commit 8310661

3 files changed

Lines changed: 319 additions & 314 deletions

File tree

src/ByteGuard.FileValidator/Configuration/ConfigurationValidator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public static void ThrowIfInvalid(FileValidatorConfiguration configuration)
3636
}
3737

3838
// Validate file type is supported by the current version of FileValidator.
39-
if (!FileValidator.SupportedFileDefinitions.Any(f => f.FileType.Equals(fileType)))
39+
if (!FileDefinitions.SupportedFileDefinitions.Any(f => f.FileType.Equals(fileType)))
4040
{
4141
throw new UnsupportedFileException($"File type '{fileType}' is not supported in the current version of FileValidator.");
4242
}
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
using ByteGuard.FileValidator.Models;
2+
3+
namespace ByteGuard.FileValidator;
4+
5+
internal static class FileDefinitions
6+
{
7+
/// <summary>
8+
/// List of all supported valid file definitions, incl. their header signatures (magic numbers)
9+
/// and potentially their corresponding valid subtype signatures.
10+
/// </summary>
11+
internal static readonly List<FileDefinition> SupportedFileDefinitions = new List<FileDefinition>
12+
{
13+
new FileDefinition
14+
{
15+
FileType = FileExtensions.Jpeg,
16+
ValidSignatures = new List<byte[]>
17+
{
18+
new byte[] { 0xFF, 0xD8, 0xFF } // ÿØÿ
19+
}
20+
},
21+
new FileDefinition
22+
{
23+
FileType = FileExtensions.Jpg,
24+
ValidSignatures = new List<byte[]>
25+
{
26+
new byte[] { 0xFF, 0xD8, 0xFF } // ÿØÿ
27+
}
28+
},
29+
new FileDefinition
30+
{
31+
FileType = FileExtensions.Jpe,
32+
ValidSignatures = new List<byte[]>
33+
{
34+
new byte[] { 0xFF, 0xD8, 0xFF } // ÿØÿ
35+
}
36+
},
37+
new FileDefinition
38+
{
39+
FileType = FileExtensions.Pdf,
40+
ValidSignatures = new List<byte[]>
41+
{
42+
new byte[] { 0x25, 0x50, 0x44, 0x46, 0x2D } // %PDF-
43+
}
44+
},
45+
new FileDefinition
46+
{
47+
FileType = FileExtensions.Png,
48+
ValidSignatures = new List<byte[]>
49+
{
50+
new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } // ‰PNG␍␊␚␊
51+
}
52+
},
53+
new FileDefinition
54+
{
55+
FileType = FileExtensions.Bmp,
56+
ValidSignatures = new List<byte[]>
57+
{
58+
new byte[] { 0x42, 0x4D } // BM
59+
}
60+
},
61+
new FileDefinition
62+
{
63+
FileType = FileExtensions.Doc,
64+
ValidSignatures = new List<byte[]>
65+
{
66+
new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } // ÐÏ␑ࡱ␚á
67+
}
68+
},
69+
new FileDefinition
70+
{
71+
FileType = FileExtensions.Docx,
72+
// WARNING: This shares the same signature as .zip and could potentially allow for .zip disguised as .docx.
73+
ValidSignatures = new List<byte[]>
74+
{
75+
new byte[] { 0x50, 0x4B, 0x03, 0x04 } // PK␃␄
76+
}
77+
},
78+
new FileDefinition
79+
{
80+
FileType = FileExtensions.Odp,
81+
// WARNING: This shares the same signature as .zip and could potentially allow for .zip disguised as .odp.
82+
ValidSignatures = new List<byte[]>
83+
{
84+
new byte[] { 0x50, 0x4B, 0x03, 0x04 } // PK␃␄
85+
}
86+
},
87+
new FileDefinition
88+
{
89+
FileType = FileExtensions.Ods,
90+
// WARNING: This shares the same signature as .zip and could potentially allow for .zip disguised as .ods.
91+
ValidSignatures = new List<byte[]>
92+
{
93+
new byte[] { 0x50, 0x4B, 0x03, 0x04 } // PK␃␄
94+
}
95+
},
96+
new FileDefinition
97+
{
98+
FileType = FileExtensions.Odt,
99+
// WARNING: This shares the same signature as .zip and could potentially allow for .zip disguised as .odt.
100+
ValidSignatures = new List<byte[]>
101+
{
102+
new byte[] { 0x50, 0x4B, 0x03, 0x04 } // PK␃␄
103+
}
104+
},
105+
new FileDefinition
106+
{
107+
FileType = FileExtensions.Rtf,
108+
ValidSignatures = new List<byte[]>
109+
{
110+
new byte[] { 0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31 } // {\rtf1
111+
}
112+
},
113+
new FileDefinition
114+
{
115+
FileType = FileExtensions.Xlsx,
116+
// WARNING: This shares the same signature as .zip and could potentially allow for .zip disguised as .xlsx.
117+
ValidSignatures = new List<byte[]>
118+
{
119+
new byte[] { 0x50, 0x4B, 0x03, 0x04 } // PK␃␄
120+
}
121+
},
122+
new FileDefinition
123+
{
124+
FileType = FileExtensions.Xls,
125+
ValidSignatures = new List<byte[]>
126+
{
127+
new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } // ÐÏ␑ࡱ␚á
128+
}
129+
},
130+
new FileDefinition
131+
{
132+
FileType = FileExtensions.Pptx,
133+
// WARNING: This shares the same signature as .zip and could potentially allow for .zip disguised as .pptx.
134+
ValidSignatures = new List<byte[]>
135+
{
136+
new byte[] { 0x50, 0x4B, 0x03, 0x04 } // PK␃␄
137+
}
138+
},
139+
new FileDefinition
140+
{
141+
FileType = FileExtensions.M4a,
142+
ValidSignatures = new List<byte[]>
143+
{
144+
new byte[] { 0x66, 0x74, 0x79, 0x70 } // ftyp
145+
},
146+
SignatureOffset = 4,
147+
HasSubtype = true,
148+
SubtypeOffset = 8,
149+
ValidSubtypeSignatures = new List<byte[]>
150+
{
151+
new byte[] { 0x4D, 0x34, 0x41, 0x20 } // M4A_
152+
}
153+
},
154+
new FileDefinition
155+
{
156+
FileType = FileExtensions.Mov,
157+
ValidSignatures = new List<byte[]>
158+
{
159+
new byte[] { 0x66, 0x74, 0x79, 0x70 } // ftyp
160+
},
161+
SignatureOffset = 4,
162+
HasSubtype = true,
163+
SubtypeOffset = 8,
164+
ValidSubtypeSignatures = new List<byte[]>
165+
{
166+
new byte[] { 0x71, 0x74, 0x20, 0x20 } // qt__ (Quicktime)
167+
}
168+
},
169+
new FileDefinition
170+
{
171+
FileType = FileExtensions.Avi,
172+
ValidSignatures = new List<byte[]>
173+
{
174+
new byte[] { 0x52, 0x49, 0x46, 0x46 } // RIFF
175+
},
176+
HasSubtype = true,
177+
SubtypeOffset = 8,
178+
ValidSubtypeSignatures = new List<byte[]>
179+
{
180+
new byte[] { 0x41, 0x56, 0x49, 0x20 } // AVI_
181+
}
182+
},
183+
new FileDefinition
184+
{
185+
FileType = FileExtensions.Mp3,
186+
ValidSignatures = new List<byte[]>
187+
{
188+
new byte[] { 0xFF, 0xFB }, // Without ID3 tag
189+
new byte[] { 0xFF, 0xF2 }, // Without ID3 tag
190+
new byte[] { 0xFF, 0xF3 }, // Without ID3 tag
191+
new byte[] { 0x49, 0x44, 0x33 } // ID3
192+
}
193+
},
194+
new FileDefinition
195+
{
196+
FileType = FileExtensions.Mp4,
197+
ValidSignatures = new List<byte[]>
198+
{
199+
new byte[] { 0x66, 0x74, 0x79, 0x70 } // ftyp
200+
},
201+
SignatureOffset = 4,
202+
HasSubtype = true,
203+
SubtypeOffset = 8,
204+
ValidSubtypeSignatures = new List<byte[]>
205+
{
206+
new byte[] { 0x6D, 0x6D, 0x70, 0x34 }, // mmp4 (MP4)
207+
new byte[] { 0x6D, 0x70, 0x34, 0x32 }, // mp42 (MP4 v2)
208+
new byte[] { 0x69, 0x73, 0x6F, 0x6D }, // isom (ISO Base Media File)
209+
new byte[] { 0x4D, 0x53, 0x4E, 0x56 } // MSNV (MPEG-4)
210+
}
211+
},
212+
new FileDefinition
213+
{
214+
FileType = FileExtensions.Wav,
215+
ValidSignatures = new List<byte[]>
216+
{
217+
new byte[] { 0x52, 0x49, 0x46, 0x46 } // RIFF
218+
},
219+
HasSubtype = true,
220+
SubtypeOffset = 8,
221+
ValidSubtypeSignatures = new List<byte[]>
222+
{
223+
new byte[] { 0x57, 0x41, 0x56, 0x45 } // WAVE
224+
}
225+
},
226+
new FileDefinition
227+
{
228+
FileType = FileExtensions.Txt,
229+
AllowMissingSignature = true
230+
},
231+
new FileDefinition
232+
{
233+
FileType = FileExtensions.Csv,
234+
AllowMissingSignature = true
235+
},
236+
new FileDefinition
237+
{
238+
FileType = FileExtensions.Ico,
239+
ValidSignatures = new List<byte[]>
240+
{
241+
new byte[] { 0x00, 0x00, 0x01, 0x00 }, // ␀␀␁␀
242+
}
243+
},
244+
new FileDefinition
245+
{
246+
FileType = FileExtensions.Heic,
247+
ValidSignatures = new List<byte[]>
248+
{
249+
new byte[] { 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63 } // ftypheic
250+
},
251+
SignatureOffset = 4
252+
},
253+
new FileDefinition
254+
{
255+
FileType = FileExtensions.Gif,
256+
ValidSignatures = new List<byte[]>
257+
{
258+
new byte[] { 0x47, 0x49, 0x46, 0x38 }, // GIF8
259+
}
260+
},
261+
new FileDefinition
262+
{
263+
FileType = FileExtensions.Tif,
264+
ValidSignatures = new List<byte[]>
265+
{
266+
new byte[] { 0x49, 0x49, 0x2A, 0x00 }, // II*␀ (Intel byte order)
267+
new byte[] { 0x4D, 0x4D, 0x00, 0x2A }, // MM␀* (Motorola byte order)
268+
new byte[] { 0x49, 0x49, 0x2B, 0x00 }, // II+␀ (BigTIFF, Intel byte order)
269+
new byte[] { 0x4D, 0x4D, 0x00, 0x2B } // MM␀+ (BigTIFF, Motorola byte order)
270+
}
271+
},
272+
new FileDefinition
273+
{
274+
FileType = FileExtensions.Tiff,
275+
ValidSignatures = new List<byte[]>
276+
{
277+
new byte[] { 0x49, 0x49, 0x2A, 0x00 }, // II*␀ (Intel byte order)
278+
new byte[] { 0x4D, 0x4D, 0x00, 0x2A }, // MM␀* (Motorola byte order)
279+
new byte[] { 0x49, 0x49, 0x2B, 0x00 }, // II+␀ (BigTIFF, Intel byte order)
280+
new byte[] { 0x4D, 0x4D, 0x00, 0x2B } // MM␀+ (BigTIFF, Motorola byte order)
281+
}
282+
},
283+
new FileDefinition
284+
{
285+
FileType = FileExtensions.Ogg,
286+
ValidSignatures = new List<byte[]>
287+
{
288+
new byte[] { 0x4F, 0x67, 0x67, 0x53 } // OggS
289+
}
290+
},
291+
new FileDefinition
292+
{
293+
FileType = FileExtensions.Oga,
294+
ValidSignatures = new List<byte[]>
295+
{
296+
new byte[] { 0x4F, 0x67, 0x67, 0x53 } // OggS
297+
}
298+
},
299+
new FileDefinition
300+
{
301+
FileType = FileExtensions.Ogv,
302+
ValidSignatures = new List<byte[]>
303+
{
304+
new byte[] { 0x4F, 0x67, 0x67, 0x53 } // OggS
305+
}
306+
},
307+
new FileDefinition
308+
{
309+
FileType = FileExtensions.Ogx,
310+
ValidSignatures = new List<byte[]>
311+
{
312+
new byte[] { 0x4F, 0x67, 0x67, 0x53 } // OggS
313+
}
314+
}
315+
};
316+
}

0 commit comments

Comments
 (0)