STRAN.SI

Upload STL in grafike

Varnost, validacija, antivirus, pretvorba, varna hramba. Iz produkcije Originate.direct in 3DKristal.si.

← Vsi članki
Tehnično 8 min branja

Varnost, validacija, pretvorba, antivirus. Iz produkcije Originate.direct in 3DKristal.si.

Problem: upload je najbolj občutljiv vektor varnosti

Vsak upload je potencialno nevaren. Zlonameren uporabnik lahko naloži PHP datoteko z malicious kode in jo izvaja na strežniku. Slika je lahko zip bomba, PDF lahko vsebuje JavaScript, ki ga ranljivi PDF reader izvaja. Upload modul mora biti hkrati prijazen in varen.

Validacija – več plasti

1. Whitelisting extension

Sprejmemo SAMO tiste extensije, ki jih pričakujemo:

$allowed = ['stl', 'jpg', 'jpeg', 'png', 'pdf', 'ai', 'eps'];
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!in_array($ext, $allowed)) {
    throw new RuntimeException('Format datoteke ni podprt.');
}

2. MIME type check

Brskalnik lahko laže o MIME tipu. Preverimo s `finfo`:

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $tmp_name);
finfo_close($finfo);

$allowed_mimes = [
    'application/sla',          // STL ASCII
    'application/octet-stream', // STL binary
    'image/jpeg',
    'image/png',
    'application/pdf',
    'application/postscript',   // AI, EPS
];
if (!in_array($mime, $allowed_mimes)) {
    throw new RuntimeException('MIME tip ne ustreza.');
}

3. Velikost

Max 50 MB v PHP-ju + na strežniku (post_max_size, upload_max_filesize). Pri STL datotekah pogosto več kot 100 MB – obvestilo stranki, da raje pošlje compressed ZIP.

4. STL header check (za 3D datoteke)

STL ima specifičen format. Binary STL začenja z 80-byte header, ASCII STL pa s "solid". Preverimo prvih nekaj bajtov:

$fp = fopen($tmp_name, 'rb');
$header = fread($fp, 100);
fclose($fp);

$isAsciiStl = str_starts_with(trim($header), 'solid');
$isBinaryStl = strlen($header) === 100; // dovolj dolg za header
if (!$isAsciiStl && !$isBinaryStl) {
    throw new RuntimeException('STL datoteka ni veljavna.');
}

Antivirus – ClamAV

Pri produkcijskih sistemih z file uploadom močno priporočamo antivirus skener. Najpogosteje ClamAV:

exec('clamscan --no-summary ' . escapeshellarg($tmp_name), $output, $code);
if ($code !== 0) {
    unlink($tmp_name);
    throw new RuntimeException('Datoteka je okužena z virusom.');
}

Varna hramba

  • IZVEN webroot-a: `/private/uploads/`, ne `/public_html/uploads/`. Tako PHP ne more izvajati naloženih datotek.
  • Naključno ime: ne `.stl`, ampak `-.stl`. Preprečuje overwrite napada.
  • Brez izvedbenih pravic: chmod 644 (rw-r--r--), brez x bit-a.
  • .htaccess v upload mapi: `php_flag engine off` – tudi če pride PHP datoteka, se ne izvede.

Pretvorba in optimizacija

JPG / PNG → WebP

$image = imagecreatefromjpeg($source);
imagewebp($image, $destination, 80); // kakovost 80
imagedestroy($image);

STL → 3D preview slika

Pri Originate.direct smo uporabili Three.js za 3D preview v brskalniku + server-side render z OpenSCAD ali Blender CLI za statične preview slike.

PDF → JPG preview

S `imagick` ali `pdftoppm`:

$im = new Imagick();
$im->setResolution(150, 150);
$im->readImage($pdf_path . '[0]'); // prva stran
$im->setImageFormat('jpeg');
$im->writeImage($preview_path);

UX – kar stranka vidi

Drag & drop

Vlečenje datotek v polje + klik-za-izbiro fallback. HTML5 native:

<input type="file" id="upload" multiple accept=".stl,.jpg,.png,.pdf">

Progress bar

Pri večjih datotekah (STL > 10 MB) prikažemo upload progress. XMLHttpRequest s progress event-om.

Preview pred submitom

Pri slikah: thumbnail v brskalniku. Pri STL: 3D preview z Three.js (opcijsko).

Realne implementacije

  • Originate.direct: STL upload za 3D tisk, PayPal plačilo, e-mail prodajalcu.
  • 3DKristal.si: foto upload za pregled. Brezplačen pregled pred plačilom.
  • Broška.si: grafika za broške – PDF, AI, EPS, JPG, PNG.
  • Cut.si: grafika za tisk na majice ali izrez folije.

Imate vprašanje glede članka ali konkretnega primera?

Pošljite kratek opis svojega primera. Odgovorimo z realno usmeritvijo – tudi če ne potrebujete naših storitev.

Pokliči Povpraševanje