Re: Väntrum model Y Juniper
Postat: 11 mar 2026 19:42
Mycket bra inlägg och viktigt att se över.enoch85 skrev: ↑11 mar 2026 19:25Heads up alla som använder olika appar i blindo:
Säkerhetsgranskning: tesla-order-status
Repository: chrisi51/tesla-order-status
Granskad version: p1.2.5
Datum: 2026-03-11
Utfört och (dåligt) översatt av Claude Opus 4.6
Jag har gått igenom hela kodbasen och sammanställt de säkerhetsproblem jag hittade. Totalt 16 fynd, sorterade efter allvarlighetsgrad.
Kritiskt — Leveranskedjan / fjärrkörning av kod
1. Osignerad auto-uppdaterare som kör godtycklig kod
Filer: app/update_check.py:128–154, hotfix.py:36–70
Både auto-uppdateraren och hotfix-skriptet laddar ner en ZIP från GitHub, packar upp den över hela installationskatalogen och — i auto-uppdaterarens fall — kör omedelbart om processen via os.execv().
Det finns ingen signaturverifiering, ingen checksumma-validering, ingen hash-pinning. Om en angripare kan utföra en MITM-attack (t.ex. på publikt Wi-Fi eller via DNS-förgiftning), kompromettera GitHub-kontot, eller få in skadlig kod via en pull request, får de full kodexekvering på varje användares maskin som kör uppdateraren.
perform_update() avslutas med:
Skriptet startas alltså om med den nyss överskrivna koden utan att verifiera att innehållet är säkert. Inställningen "automatically" gör detta helt tyst.Kod: Markera allt
os.execv(sys.executable, [sys.executable] + sys.argv)
Allvarlighetsgrad: Kritisk
Rekommendation: Pinna SHA-256-hashar per release eller verifiera GPG-signaturer. Använd helst ett signerat manifest. Kör aldrig os.execv() direkt efter uppackning av opålitlig kod.
2. Zip Slip — path traversal vid uppackning
Filer: hotfix.py:62, update_check.py:140
Båda filerna använder extractall() eller shutil.unpack_archive() utan att kontrollera att de uppackade filnamnen håller sig inom målkatalogen. Ett manipulerat arkiv kan innehålla sökvägar som ../../../.bashrc och skriva över godtyckliga filer.
Allvarlighetsgrad: Kritisk (i kombination med den osignerade uppdateraren)
Rekommendation: Validera varje sökväg innan uppackning:
Kod: Markera allt
for member in zf.namelist(): resolved = (Path(tmpdir) / member).resolve() if not str(resolved).startswith(str(Path(tmpdir).resolve())): raise ValueError(f"Path traversal detected: {member}")
3. Godtycklig kodexekvering via migrationshanteraren
Fil: app/utils/migration.py:39–44
Migrationshanteraren laddar och kör dynamiskt alla .py-filer i app/migrations/ via importlib. Eftersom auto-uppdateraren tyst kan leverera nya migrationsfiler (se fynd #1), är detta en andra exekveringsväg för injicerad kod.
Allvarlighetsgrad: Hög (beroende av #1)
Rekommendation: Migrationer bör vara deklarativa datatransformeringar, inte godtycklig Python. Om kodexekvering krävs, signera migrationsfilerna individuellt.
Högt — Token- och autentiseringssäkerhet
4. Tokens sparas som klartext-JSON utan filrättighetsbegränsningar
Fil: app/utils/auth.py:84–86
Teslas OAuth-tokens (inklusive den långlivade refresh-tokenen) skrivs till data/private/tesla_tokens.json som ren JSON. Inga filrättigheter sätts, så på fleranvändarsystem innebär standardvärdet för umask (typiskt 0022) att andra användare kan läsa filen. En stulen refresh-token ger bestående åtkomst till offrets Tesla-konto.
Allvarlighetsgrad: Hög
Rekommendation: Sätt restriktiva rättigheter direkt efter skapandet (os.chmod(path, 0o600)). Överväg att kryptera tokens i vila eller använda OS-nyckelringen (t.ex. via keyring-biblioteket).
5. JWT-validering kontrollerar bara utgångstid — ingen signaturverifiering
Fil: app/utils/auth.py:96–98
JWT-payloaden avkodas för att kontrollera exp-fältet, men den kryptografiska signaturen verifieras aldrig. Om tokenfilen manipuleras (t.ex. av skadlig programvara) accepterar skriptet en förfalskad token med framtida utgångstid. Padding-hacket + '==' kan dessutom ge felaktig avkodning för vissa payloads.Kod: Markera allt
def _is_token_valid(access_token): jwt_decoded = json.loads(base64.b64decode(access_token.split('.')[1] + '==').decode('utf-8')) return jwt_decoded['exp'] > time.time()
Allvarlighetsgrad: Medel–Hög
Rekommendation: Använd base64.urlsafe_b64decode med korrekt padding-beräkning. Överväg att verifiera JWT-signaturen mot Teslas publika nycklar, eller åtminstone behandla ett misslyckat API-anrop som signal att autentisera om.
6. OAuth state-parametern valideras aldrig
Fil: app/utils/auth.py:23, 64–70
OAuth state-parametern genereras och skickas i auktoriserings-URL:en, men efter att användaren klistrar in omdirigerings-URL:en kontrolleras aldrig det returnerade värdet. Det här motverkar CSRF-skyddet som state-parametern är avsedd att ge.
Allvarlighetsgrad: Medel
Rekommendation: Extrahera och jämför state-parametern från omdirigerings-URL:en med det genererade värdet innan autentiseringen fortsätter.
Medel — Dataexfiltrering och integritet
7. Beständigt fingeravtryck i telemetri
Filer: app/utils/telemetry.py:74–134, app/config.py:14
När telemetri är aktiverat skickas en JSON-payload till tesla-order-status-tracker.de/push/telemetry.php med ett beständigt installationsfingeravtryck, pseudonymiserade order-ID:n, Tesla-modell, locale, CLI-flaggor och skriptversion. Fingeravtrycket genereras en gång och återanvänds för alltid, vilket möjliggör långsiktig spårning av individuella installationer.
Allvarlighetsgrad: Medel
Rekommendation: Rotera fingeravtrycket periodiskt. Dokumentera tydligare vilken data som skickas.
8. Påträngande omsamtycke för telemetri
Fil: app/utils/telemetry.py:35–47
Om användaren tackar nej till telemetri frågar skriptet igen var tionde körning. Meddelandet ("Naww, I've counted on you! =(") använder känslomässig press. Det här är ett mörkt mönster som undergräver användarens tillit.
Allvarlighetsgrad: Låg–Medel
Rekommendation: Respektera användarens val. Fråga en gång; erbjud en CLI-flagga eller konfigurationsalternativ för de som ändrar sig.
9. Optionskoder skickas till extern server
Filer: app/utils/option_codes.py:14, app/utils/telemetry.py:124–134
Optionskoder hämtas från och laddas upp till tesla-order-status-tracker.de. Även om enskilda koder inte är känsliga identifierar kombinationen unikt en fordonskonfiguration, och skickas tillsammans med det beständiga fingeravtrycket.
Allvarlighetsgrad: Låg–Medel
Rekommendation: Gör optionskodsrapportering till ett separat opt-in (skilt från generell telemetri).
Medel — Indatavalidering och felhantering
10. Ren except: fångar SystemExit och KeyboardInterrupt
Fil: app/config.py:39
Fångar allt, inklusive SystemExit, KeyboardInterrupt och MemoryError. Det kan dölja kritiska fel och förhindra ordentlig nedstängning.Kod: Markera allt
except: TESLA_STORES = {}
Allvarlighetsgrad: Låg–Medel
Rekommendation: Använd except Exception: som minimum.
11. Ingen explicit TLS-certifikatsverifiering
Fil: app/utils/connection.py
request_with_retry använder requests.get/post utan att explicit ange verify=True. Även om requests har det som standard skyddar kodbasen inte mot att miljövariabler manipuleras. Värt att tänka på eftersom tokens skickas i Authorization-headers.
Allvarlighetsgrad: Låg–Medel
Rekommendation: Ange verify=True explicit i alla anrop.
12. XML-parsning utan skydd mot entitetsexpansion
Fil: app/update_check.py:72
Atom-feeden parsas med xml.etree.ElementTree som är sårbar för "billion laughs"-attacker (exponentiell entitetsexpansion). Även om GitHub knappast serverar ett skadligt feed kan en MITM-angripare göra det.Kod: Markera allt
root = ET.fromstring(resp.content)
Allvarlighetsgrad: Låg–Medel
Rekommendation: Använd defusedxml.ElementTree eller sätt en parser med expansionsbegränsningar.
13. Regex-baserad JSON-reparation i konfigurationsladdaren
Fil: app/config.py:56
Regexet tar bort avslutande kommatecken för att tolerera felformaterad JSON, men det kan även matcha inuti strängvärden och korrumpera data (t.ex. "tags": "a, }" skulle förvanskas).Kod: Markera allt
text = re.sub(r",\s*([\]\}])", r"\1", text)
Allvarlighetsgrad: Låg
Rekommendation: Använd en JSON-parser som hanterar avslutande komman (t.ex. json5) eller ta bort workarounden.
Lågt — Övrigt
14. Clipboard-injektion med reklam
Fil: app/utils/orders.py:399–403
I share-läge kopieras data tyst till urklipp med en bifogad reklamtext. Även i normalt läge anropas generate_share_output som kopierar till urklipp som bieffekt. Användare kan omedvetet klistra in reklam.
Allvarlighetsgrad: Låg
Rekommendation: Kopiera till urklipp bara när användaren explicit använder --share. Ta bort reklaminjektionen.
15. Okodade värden i URL
Fil: app/utils/orders.py:237–240
order_id, LANGUAGE och COUNTRY interpoleras rakt in i en URL utan URL-kodning. Om något av värdena innehåller specialtecken bryts URL-strukturen.
Allvarlighetsgrad: Låg
Rekommendation: Använd urllib.parse.urlencode eller requests params-dict.
16. Överdriven backoff-fördröjning
Fil: app/utils/connection.py:68
Vid 5xx-fel är retry-fördröjningen 5 ** attempt sekunder (1, 5, 25). 25 sekunders väntan vid tredje försöket är onödigt lång och det saknas ett övre tak samt jitter.
Allvarlighetsgrad: Låg
Rekommendation: Använd exponentiell backoff med jitter och ett rimligt tak.
Sammanfattning
Tre viktigaste åtgärderna
- #1–2 (Kritisk): Osignerad uppdaterare + Zip Slip — leveranskedjeattack som ger fjärrkörning av kod.
- #3 (Hög): Migrationshanteraren kör godtyckliga .py-filer som kan levereras via uppdateraren.
- #4 (Hög): Tokens i klartext utan filrättighetsbegränsningar — ger tillgång till Tesla-kontot.
- #5 (Medel–Hög): JWT-expiry kontrolleras utan signaturverifiering.
- #6 (Medel): OAuth state-parameter valideras aldrig — CSRF-risk.
- #7–9 (Medel): Beständig fingeravtrycksspårning och optionskodsdelning via telemetri.
- #10–12 (Låg–Medel): Bred felhantering, implicit TLS, osäker XML-parsning.
- #13–16 (Låg): Regex-korruption, reklam i urklipp, okodade URL-värden, överdriven backoff.
- Signera eller hasha releaser och verifiera innan uppdateringar tillämpas. Ta bort os.execv() efter blind uppackning.
- Begränsa filrättigheter på tesla_tokens.json till enbart ägaren (0o600) och överväg OS-nyckelringsintegration.
- Validera OAuth state-parametern vid omdirigering för att stänga CSRF-luckan.
Jag forkade projektet och rensa bort mycket sånt jag tyckte var onödigt.
Bla det första som försvann var just telemetri biten.
Kan länka min fork om det önskas av någon här