Le but de ce projet est de partager des manières alternatives d'accéder aux API de la SNCF.
La SNCF fournit une API publique numerique.sncf.com/api à travers son partenaire Navitia.
L'API est généreuse en termes d'usage pour les développeurs (gratuitement: 150 000 requêtes/mois (5000 requêtes/jour)) et pratique pour des tâches complexes de calcul d'itinéraire. Par je contre, la qualité des données en direct n'est pas au rendez-vous.
- D'expérience sur les TER, les petits retards sur les trains ne sont pas référencés sur l'API Navitia alors que bien indiqués sur le site internet garesetconnexions.sncf ou l'Appli Gare
- Les justifications de retard restent souvent génériques sur l'API public de la SNCF alors l'affichage voyageur décrit plus précisément la situation.
- Mais surtout... il manque le numéro de voie des trains en gare! Pas disponible sur Navitia.
L'idée est de voir comment les applications officiels récupèrent des informations plus à jour. De manière générale les applications SNCF se basent sur une API nommé PIV: Portail d'Information Voyageurs. Donc des données à destination des voyageurs.
Historiquement, sncf.com permettait d'avoir accès aux horaires des trains, mais le site à été remplacé progressivement par garesetconnexions.sncf depuis 2022:
Comme pour sncf.com, les sites de la SNCF sont protégés contre le scraping: via Datadome: SNCF Connect réduit ses coûts d'infrastructure de 10%. La protection est plutôt efficace, même avec une IP résidentielle c'est dur de ne pas se faire détecter. On tombe rapidement sur un captcha à remplir.
- Pour Paris Montparnasse l'API Json qui renvoie les horaires des trains est ici: https://www.garesetconnexions.sncf/schedule-table/Departures/0087391003 avec 0087391003 facilement récupérable via Navitia qui correspond à l'identifiant de la gare.
Quand j'ai commencé à utiliser les API SNCF, garesetconnexions.sncf était à ses débuts et l'accès aux horaires ne se faisait pas via cet url. A vrai dire il y a des chances que garesetconnexions.sncf/schedule-table ne soit qu'un reverse proxy vers la vraie API. Il y a des traces de cela dans le header HTTP de réponse:
- content-security-policy: [...] https://sncf-appligares-qualification.azurewebsites.net [...] https://garesetconnexions-qualification.azure-api.net [...]
Malheureusement ce sont des URLs de qualification et les retours d'API sont vides. En 2023 l'API de production était https://garesetconnexions-online.azure-api.net (elle est toujours utilisée pour l'application Android). On pouvait même accéder au portail développeur:
| Point de terminaison | Configuration du point de terminaison |
|---|---|
| API Gateway | contosointernalvnet.azure-api.net |
| Portail des développeurs | contosointernalvnet.portal.azure-api.net |
| Le nouveau portail des développeurs | contosointernalvnet.developer.azure-api.net |
| Point de terminaison de la gestion directe | contosointernalvnet.management.azure-api.net |
| Git | contosointernalvnet.scm.azure-api.net |
La clé d'API était disponible dans la page HTML du client web.
Cette page est un peu mystérieuse car elle sort de nulle part. Mais je l'ai découverte via Google car le swagger est référencé: L'openAPI est disponible dans ce projet sncf-appligares-qualification-slot303d.swagger.json
A la différence du swagger https://sncf-appligares-qualification.azurewebsites.net qui ne renvoie que des réponses vides, ici les réponses correspondent aux vraies retours de l'API PIV. L'avantage est que c'est une API Azure, il n'y a pas de limite d'usage. C'est une première solution, mais il y a des chances que cette
Comment obtenir une clé d'API (clé de souscription dans Azure)? D'après la documentation elle doit être indiquée dans l'en-tête Ocp-Apim-Subscription-Key: Voir la documentation d'Azure https://learn.microsoft.com/en-us/azure/api-management/api-management-subscriptions#use-a-subscription-key
Dans le cas du site web garesetconnexions.sncf, comme je l'ai indiqué, la clé d'API n'existe plus dans la page HTML directement. Mais comment fonctionne l'application android Ma Gare SNCF ?
Le plus simple est d'installer un intercepteur de trafic dans un émulateur Android:
- https://httptoolkit.com/: VPN/Proxy pour intercepter le trafic HTTPS.
- https://github.com/levyitay/AddSecurityExceptionAndroid: Pour modifier un APK afin d'autoriser les certificats CA utilisateur.
Si on analyse le trafic, on verra que les requêtes partent bien vers garesetconnexions-online.azure-api.net. On peut alors récupérer la clé d'accès associée. Ce qui veut dire que dans le cas des applications mobiles, les utilisateurs attaquent directement l'API Azure en direct, sans passer par aucune protection.
Solution alternative, car on sait que la clé d'API Azure fait 32 caractères en base 16, on peut utiliser grep directerement sur l'archive binaire de l'APK:
$ grep -a -E -o '\b[a-f0-9]{32}\b' ma-gare-sncf-4-8-2.apk
[...]
aaaabbbbccccdddd1111222233334444
[...]Cela liste 6-7 secrets candidats qu'il faut tester 1 par 1:
$ curl -H "Ocp-Apim-Subscription-Key: aaaabbbbccccdddd1111222233334444" "https://garesetconnexions-online.azure-api.net/API/PIVProxy/Departures/0087391003"
[{"direction":"Departure","trainNumber":[...]}]Ensuite, libre d'utiliser l'ensemble des points d'accès disponibles dans le Swagger.

