Un scan, puis une pull request

Scandar n'écrit pas sur la branche par défaut. Le correctif reste sur scandar/fix-… jusqu'à ce que vous le fusionniez.

Ce que fait un scan

  1. Connectez-vous avec la GitHub App. Seuls les dépôts choisis à l'installation sont visibles.
  2. Recherche des projets : un package.json à côté de package-lock.json, pnpm-lock.yaml ou yarn.lock. Les manifestes imbriqués sans lockfile propre comptent comme membres du workspace.
  3. Lecture du lockfile et interrogation d'OSV.dev. Les identifiants d'alerte en double sont fusionnés.
  4. Construction d'un plan de correction. Les dépendances directes passent à ^fixed. Les transitives sont épinglées avec overrides, pnpm.overrides ou pnpm-workspace.yaml, ou les resolutions de Yarn.
  5. Régénération du lockfile dans un dossier temporaire, scripts de paquets désactivés, puis ouverture de la branche et de la pull request.

Vous pouvez cocher des paquets précis. Les montées majeures sont décochées au départ. Plusieurs pull requests peuvent être ouvertes sur un projet, et un même paquet n'est pas corrigé deux fois.

Des pull requests de correction plus sûres

Un correctif ne propose pas de version publiée depuis moins que votre délai de version. Le délai par défaut est de 5 jours. Réglez-le dans Réglages → Pull requests, ou remplacez-le sur un projet. 0 désactive le délai. Le maximum est de 90 jours.

Scandar lit la date de publication de chaque version npm et vérifie la version qui arrive réellement dans le lockfile. Une plage qui glisserait vers une version plus récente est épinglée sur la version admissible. Si rien d'assez ancien n'existe encore, le correctif est reporté et la page indique quand il sera éligible. Une alerte critique, une vulnérabilité exploitée connue ou un paquet malveillant reste proposé, avec un avertissement indiquant que la version est récente.

Quand package.json accepte déjà la version corrigée, seul le lockfile change. npm utilise npm update --min-release-age et pnpm minimumReleaseAge. Yarn 1 n'a pas d'équivalent : la version résolue est vérifiée après coup et épinglée si elle est trop récente. Python, Go, Rust, PHP et Ruby appliquent le délai quand leurs registres renvoient les dates de publication. Sinon, la pull request indique que le délai n'a pas été appliqué.

La pull request comporte une section « Why this version » : le correctif OSV, la version choisie, sa date de publication, le délai, toute exception et les versions plus récentes écartées. Une montée majeure affiche un risque de rupture faible, moyen, élevé ou inconnu, d'après les notes de version publiques, les moteurs Node et les dépendances pairs. Les montées majeures restent décochées. L'auto-merge est désactivé tant que vous ne l'activez pas. Il ne fusionne en squash qu'un correctif patch ou mineur, jamais un override transitif, seulement quand toutes les vérifications sont vertes et que vous pouvez toujours pousser.

Écosystèmes

ÉcosystèmeFichiersCorrectif automatique
npmpackage-lock.json, pnpm-lock.yaml, yarn.lockOui, sauf Yarn Berry
Pythonpoetry.lock, uv.lock, Pipfile.lock, requirements.txt épinglé avec ==Indiqué, non appliqué
Gogo.modIndiqué, non appliqué
RustCargo.lockIndiqué, non appliqué
PHPcomposer.lockIndiqué, non appliqué
RubyGemfile.lockIndiqué, non appliqué

Permissions de la GitHub App

PermissionUtilisée pour
ContentsLire les fichiers, créer la branche et le commit.
Pull requestsOuvrir, fusionner en squash et fermer.
MetadataLecture. Accordée par défaut.
ChecksLire la CI avant une fusion et écrire la vérification Scandar.
Commit statusesLecture, pour la même décision de fusion.

Callback OAuth local : http://localhost:3010/api/auth/callback/github. L'app écoute sur le port 3010. npm, pnpm et yarn doivent être dans le PATH pour les lockfiles qu'ils régénèrent.

Limites

  • 10 projets par dépôt, 60 membres de workspace. Le reste est ignoré.
  • Un arbre Git tronqué se rabat sur le package.json racine.
  • La sévérité vient de database_specific.severity, puis du score CVSS v3. Sans aucun des deux, l'alerte est Inconnue.
  • La santé des paquets et les licences transitives ne couvrent que npm.
  • La régénération du lockfile expire après 3 minutes.
  • Un seul processus Node : SQLite et le bus d'événements en mémoire ne sont pas partagés entre instances.

Autour du scan

Une alerte ignorée exige une raison, une note et une durée. Elle sort des totaux, des correctifs, des notifications et des vérifications de pull request jusqu'à son expiration. L'historique garde les vulnérabilités ouvertes pendant 90 jours. Les exports sont CycloneDX 1.5, SPDX 2.3, CSV et un rapport imprimable. Un push sur la branche par défaut peut relancer un scan via le webhook de la GitHub App, et Slack ou Discord peuvent recevoir des alertes au-dessus de la sévérité choisie.

CI, CLI et éditeurs

La même vérification tourne depuis GitHub Actions, le terminal ou un agent d'éditeur. Chaque client appelle POST /api/v1/check avec une clé API. Le plan doit inclure la fonctionnalité api. Rien de tout cela n'est encore sur npm ni sur le GitHub Marketplace.

Pages publiques de paquets et d'alertes

/package/<name> (y compris @scope/name) et /cve/<id> (un identifiant CVE ou GHSA) sont publiques. Le nom est vérifié avant toute requête. Un nom non conforme, ou un paquet ou une alerte inconnus d'OSV et du registre npm, donne une 404.

La page affiche la sévérité, les versions touchées et corrigées, et KEV ou EPSS uniquement à partir des données déjà stockées ici. Le texte simplifié n'apparaît que s'il est déjà dans le cache d'explications. Ces pages n'appellent pas le modèle. L'alerte OSV reste liée, car une explication en cache peut être fausse.

Les rapports de dépôt sous /scan/… et la page imprimable /report sont en noindex. /dashboard, /admin et /api sont interdits dans robots.txt.