fix: Robustheits-Luecken aus zweitem, unabhaengigem Sicherheitsaudit behoben
Ein zweiter, unabhaengiger Audit-Durchlauf (frischer Blick, keine Vorkenntnis meiner eigenen Fixes) bestaetigte alle bisherigen Fixes als korrekt verdrahtet und fand 3 LOW-severity Robustheitsluecken - keine davon war ausnutzbar, aber alle sind jetzt behoben: - HarvestsService.create/ExtractionsService.create pruefen jetzt, dass referenzierte colonyIds/harvestIds tatsaechlich existieren, bevor die Transaktion laeuft - vorher fuehrte eine unbekannte Id zu einem ungefangenen 500 mit rohem Prisma-Fehler statt einer sauberen 400. - Etiketten-Bildelemente durchlaufen jetzt denselben Magic-Byte-Check wie Avatar-/Dokument-Uploads, statt pdfkits Bildparser ungepruefte Bytes zu uebergeben. - Webhook-Secret-Redaktion im Audit-Log nutzt jetzt explizites delete statt sich auf Prismas JSON-Serialisierung zu verlassen, die undefined-Werte verwirft (fragil, falls sich die Serialisierung mal aendert). Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
f57cffe6a8
commit
4bd7e9791a
7 files changed
+173
-7
No files matched your search
@@ -220,6 +220,75 @@ describe('LabelTemplatesService', () => {
|
||||
expect(pdf.toString('latin1')).toContain('/Image');
|
||||
});
|
||||
|
||||
it('embeds an image element whose bytes match the declared PNG mime type', async () => {
|
||||
// Minimal valid 1x1 transparent PNG, widely used as a test fixture.
|
||||
const onePixelPng =
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=';
|
||||
const imageElement: LabelElement = {
|
||||
id: 'el-img',
|
||||
type: 'image',
|
||||
x: 5,
|
||||
y: 5,
|
||||
width: 10,
|
||||
height: 10,
|
||||
src: `data:image/png;base64,${onePixelPng}`,
|
||||
};
|
||||
prisma.labelTemplate.findUnique.mockResolvedValue({
|
||||
...template,
|
||||
elements: [imageElement],
|
||||
});
|
||||
prisma.bottlingBatch.findUnique.mockResolvedValue({
|
||||
id: 'batch-1',
|
||||
jarSize: 500,
|
||||
jarCount: 1,
|
||||
lotNumber: 'L-001',
|
||||
date: new Date('2026-06-01T00:00:00.000Z'),
|
||||
bestBeforeDate: new Date('2028-06-01T00:00:00.000Z'),
|
||||
honeyBatch: { batchNumber: 'HB-001', honeyType: 'Bluetenhonig' },
|
||||
product: { name: 'Glas 500g' },
|
||||
});
|
||||
|
||||
const pdf = await service.renderLabelsPdf('template-1', 'batch-1');
|
||||
|
||||
// pdfkit always lists /ImageB /ImageC /ImageI in a page's ProcSet
|
||||
// regardless of whether anything is actually embedded, so a plain
|
||||
// "/Image" substring check would pass either way - /Subtype /Image is
|
||||
// the actual embedded-XObject marker.
|
||||
expect(pdf.toString('latin1')).toMatch(/\/Subtype\s*\/Image\b/);
|
||||
});
|
||||
|
||||
it('silently skips an image element whose bytes do not match the declared mime type', async () => {
|
||||
const mislabeled = Buffer.from('not-a-png').toString('base64');
|
||||
const imageElement: LabelElement = {
|
||||
id: 'el-img',
|
||||
type: 'image',
|
||||
x: 5,
|
||||
y: 5,
|
||||
width: 10,
|
||||
height: 10,
|
||||
src: `data:image/png;base64,${mislabeled}`,
|
||||
};
|
||||
prisma.labelTemplate.findUnique.mockResolvedValue({
|
||||
...template,
|
||||
elements: [imageElement],
|
||||
});
|
||||
prisma.bottlingBatch.findUnique.mockResolvedValue({
|
||||
id: 'batch-1',
|
||||
jarSize: 500,
|
||||
jarCount: 1,
|
||||
lotNumber: 'L-001',
|
||||
date: new Date('2026-06-01T00:00:00.000Z'),
|
||||
bestBeforeDate: new Date('2028-06-01T00:00:00.000Z'),
|
||||
honeyBatch: { batchNumber: 'HB-001', honeyType: 'Bluetenhonig' },
|
||||
product: { name: 'Glas 500g' },
|
||||
});
|
||||
|
||||
const pdf = await service.renderLabelsPdf('template-1', 'batch-1');
|
||||
|
||||
expect(pdf.subarray(0, 4).toString()).toBe('%PDF');
|
||||
expect(pdf.toString('latin1')).not.toMatch(/\/Subtype\s*\/Image\b/);
|
||||
});
|
||||
|
||||
function countPages(pdf: Buffer): number {
|
||||
const matches = pdf.toString('latin1').match(/\/Type\s*\/Page[^s]/g);
|
||||
return matches ? matches.length : 0;
|
||||
|
||||
Reference in new issue
Block a user