--- name: extract_exif_metadata kind: function lang: py domain: cybersecurity version: "1.0.0" purity: impure signature: "def extract_exif_metadata(image_path: str) -> dict" description: "Lee los metadatos EXIF de una imagen con Pillow y los devuelve normalizados (fecha, camara, software, GPS en grados decimales) mas el volcado completo de tags en `raw`. OSINT pasiva sobre documentos propios: revela cuando, con que dispositivo y donde se tomo una foto." tags: [osint-passive, exif, metadata, image, gps, forensics, pillow, extract, cybersecurity, python] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [PIL] params: - name: image_path desc: "ruta al archivo de imagen en disco (JPEG, PNG, TIFF, ...)" output: "dict con datetime, camera_make, camera_model, software, gps_lat, gps_lon (grados decimales o None) y raw (dict con todos los tags EXIF legibles por nombre). Si la imagen no tiene EXIF, los campos van a None y raw={}." tested: true tests: - "imagen sin EXIF (PNG) devuelve campos None y raw vacio" - "imagen con EXIF devuelve camara, software y fecha" - "GPSInfo DMS se convierte a grados decimales con signo por hemisferio" test_file_path: "python/functions/cybersecurity/extract_exif_metadata_test.py" file_path: "python/functions/cybersecurity/extract_exif_metadata.py" --- ## Ejemplo ```python import sys, os sys.path.insert(0, os.path.join("python", "functions")) from cybersecurity.extract_exif_metadata import extract_exif_metadata meta = extract_exif_metadata( "/home/enmanuel/Obsidian/osint/attachments/personas/objetivo_01.jpg" ) print(meta["datetime"]) # '2024:08:12 19:43:07' (cuando se tomo) print(meta["camera_model"]) # 'iPhone 13 Pro' (con que dispositivo) print(meta["gps_lat"], meta["gps_lon"]) # 40.4168 -3.7038 (donde) o None, None ``` ## Cuando usarla Cuando recolectes inteligencia pasiva sobre una imagen propia o de un objetivo y necesites saber cuando, con que dispositivo y desde donde se capturo, antes de publicarla o compartirla. Usala tambien para auditar tus propios documentos y detectar fugas de metadatos (geolocalizacion, modelo de telefono, software de edicion) antes de subirlos a un sitio publico. ## Gotchas - Funcion impura: abre el archivo del disco. Lanza si la ruta no existe o no es una imagen valida (Pillow `UnidentifiedImageError` / `FileNotFoundError`). - JPEG y HEIC de moviles suelen traer GPS embebido; PNG normalmente no lleva EXIF y devolvera todos los campos en None con `raw={}`. - El GPS revela la ubicacion fisica donde se tomo la foto — dato sensible. No lo loguees ni lo compartas sin consentimiento. - `DateTimeOriginal` vive en el sub-IFD EXIF, no en el IFD raiz; algunas imagenes solo tienen `DateTime` (fecha de modificacion del archivo), que se usa como fallback. - Las coordenadas se convierten de DMS (grados/minutos/segundos) a grados decimales y se les aplica el signo segun `GPSLatitudeRef`/`GPSLongitudeRef` (S y W => negativo).