Skip to content

Commit 3bc03e7

Browse files
committed
docs(security): limpiar hallazgos ya resueltos de SECURITY_AUDIT.md
N-1, N-2 y N-3 ya están corregidos en código — se eliminan del documento para que solo queden los riesgos aceptados y la tabla de totales.
1 parent d600d87 commit 3bc03e7

1 file changed

Lines changed: 0 additions & 56 deletions

File tree

SECURITY_AUDIT.md

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,62 +16,6 @@
1616

1717
---
1818

19-
## Hallazgos resueltos — Segunda auditoría 2026-07-29
20-
21-
### N-1 · `HelmMusicService` exportado sin permiso de bind ✅ resuelto en 9f947a3
22-
**Archivos:** `app/src/main/AndroidManifest.xml:84-91` · `audio/src/main/kotlin/dev/helm/audio/HelmMusicService.kt:41-45`
23-
**Severidad:** Alta
24-
25-
`HelmMusicService` tiene `android:exported="true"` sin `android:permission` en el `<service>`. El guard en `onGetSession` compara `controllerInfo.packageName == packageName`, pero ese valor lo suministra el caller vía `connectionHints` — no está verificado por el sistema. Cualquier app puede hacer bind y controlar la reproducción o inyectar URIs al queue de ExoPlayer.
26-
27-
**Fix:**
28-
```xml
29-
<service
30-
android:name=".HelmMusicService"
31-
android:permission="android.permission.MEDIA_CONTENT_CONTROL"
32-
android:exported="true">
33-
```
34-
En `onGetSession`: confiar solo en `controllerInfo.isTrusted`, eliminar la comparación por `packageName`.
35-
36-
---
37-
38-
### N-2 · OTA — URL de descarga sin validación de host/scheme ✅ resuelto en 36e5b05
39-
**Archivo:** `ota/src/main/kotlin/dev/helm/ota/OtaRepository.kt:45-56`
40-
**Severidad:** Alta
41-
42-
`browser_download_url` de la respuesta JSON de GitHub se pasa verbatim a `URL(apkUrl).openConnection()` sin verificar scheme ni host. `HttpURLConnection` sigue redirects por defecto. Con cuenta de GitHub comprometida o DNS poisoning se puede redirigir la descarga a un servidor arbitrario.
43-
44-
**Fix:**
45-
```kotlin
46-
val parsed = URL(apkUrl)
47-
require(parsed.protocol == "https") { "Scheme inválido" }
48-
require(
49-
parsed.host.endsWith(".github.com") ||
50-
parsed.host.endsWith(".githubusercontent.com")
51-
) { "Host no permitido" }
52-
conn.instanceFollowRedirects = false
53-
```
54-
55-
---
56-
57-
### N-3 · OTA — Comparación de firma APK con lógica `any/any` ✅ resuelto en 752900b
58-
**Archivo:** `ota/src/main/kotlin/dev/helm/ota/OtaRepository.kt:102-104`
59-
**Severidad:** Alta
60-
61-
La verificación usa `apkCerts.any { apk -> installedCerts.any { ... } }` — pasa si el APK descargado comparte **al menos un** certificado con el instalado. Si se rota la clave de firma y la anterior queda comprometida, un APK firmado con esa clave vieja seguiría pasando el check. Agravado por N-2.
62-
63-
**Fix:**
64-
```kotlin
65-
// Igualdad estricta de conjuntos
66-
require(
67-
apkCerts.map { it.toCharsString() }.toSet() ==
68-
installedCerts.map { it.toCharsString() }.toSet()
69-
)
70-
```
71-
Opción más robusta: comparar contra un fingerprint SHA-256 hardcodeado del cert de release, eliminando dependencia del runtime.
72-
73-
---
74-
7519
## Riesgos aceptados (pendiente futura iteración)
7620

7721
### A-10 · Sin Certificate Pinning para `lrclib.net`

0 commit comments

Comments
 (0)