Pour commencer, en général sur le projet. Nous avons construit un processus de développement sécurisé dans une grande société de négoce dans laquelle le service informatique dispose d'un personnel énorme et est divisé en de nombreux domaines qui sont faiblement corrélés les uns aux autres. Classiquement, ces zones peuvent être divisées en 3 groupes principaux. Le premier, un très grand groupe, est le logiciel de caisse enregistreuse, qui est écrit principalement en langage Java (90% des projets). Le deuxième groupe de systèmes le plus étendu en termes de quantité de code est celui des applications SAP. Et enfin, le troisième bloc était un "méli-mélo" de portails et d'applications mobiles: divers sites externes pour les clients de l'entreprise, des applications mobiles pour ces sites, ainsi que des ressources internes - applications mobiles et portails web pour le personnel de l'enseigne.
Le client du projet - la direction de la sécurité de l'information - a formulé la tâche générale de manière assez standard pour les trois groupes: «nous voulons avoir moins de vulnérabilités et sécuriser le développement de tous les systèmes créés au sein de l'entreprise». Mais en pratique, dans chaque département spécifique, tout était très différent de celui des autres collègues, car à chaque étape de la mise en œuvre du développement sécurisé, nous avons dû faire un million de compromis différents. Certaines nuances ont aidé à construire le processus, tandis que d'autres, au contraire, sont intervenues. Au final, nous avons quand même réussi à créer une approche plus ou moins générale pour la plupart des projets.
Nous avons formulé cette approche le plus simplement possible: le code le plus pertinent pour tous les développeurs est scanné. Si nous parlons en termes de Gitflow, et que tous les groupes de projet, à l'exception de SAP, avaient des branches de développement dans Gitflow, la branche de développement principale est scannée selon un calendrier.
Mais, comme toujours, il existe des exceptions à toute règle: l'approche générale ne peut être appliquée partout «telle quelle» pour un certain nombre de raisons. Premièrement, notre outil (analyseur de code) a plusieurs limitations du fait que nous voulons pouvoir, si nécessaire, faire l'analyse la plus approfondie de certains langages de programmation. Ainsi, dans le cas de Java, le bytecode d'analyse est beaucoup plus profond que celui du code source. Par conséquent, l'analyse des projets Java nécessitait un assemblage préalable du bytecode et seulement ensuite l'envoyer pour analyse. Dans le cas des applications C ++, Objective C et iOS, l'analyseur a été intégré au processus au stade de la construction. Nous devions également prendre en compte les différentes exigences individuelles des développeurs de tous les projets. Ci-dessous, nous décrirons comment nous avons construit le processus pour les portails et les applications mobiles.
Portails et applications mobiles
Il semble que toutes ces applications soient combinées en un seul groupe logique, mais en réalité, elles étaient un désordre terrible. Il y avait plus de 120 portails (!). L'entreprise est très grande, avec de nombreux services commerciaux, administratifs et techniques, et de temps en temps chacun d'eux décide qu'il a besoin de son propre portail et de son application mobile. Ce portail et cette application sont créés, ils sont utilisés pendant un certain temps, puis ils sont abandonnés en toute sécurité. En conséquence, au stade initial, nous avons dû effectuer un inventaire pour le client, car même les développeurs de ces applications n'avaient pas une seule liste de bases de code. Par exemple, pour gérer les référentiels de ce groupe, les développeurs ont utilisé deux GitLabs avec des administrateurs différents. De plus, parmi les portails et les applications mobiles, une part importante des projets a été mise en œuvre par développement externe.Par conséquent, lorsque l'heure de sortie approchait, les sous-traitants transféraient souvent les codes sources de la nouvelle version à l'entreprise presque sur une clé USB. En conséquence, la société avait un zoo de diverses applications et un désordre complet dans leur code. Nous devions faire une liste de tous les projets, trouver tous les responsables - responsables techniques, chefs d'équipe, puis convenir avec le client principal - le service de sécurité de l'information, lequel d'entre eux nous analyserons.
En conséquence, nous avons choisi des systèmes de production et des logiciels pris en charge pour l'analyse, sans toucher du tout aux systèmes d'archivage. Un certain nombre d'applications internes ont été considérées comme non critiques, car elles ne pouvaient causer aucun dommage financier à l'entreprise et n'ont pas été sélectionnées pour analyse. Par exemple, un système de gestion pour les emballeurs dans un entrepôt ou des chargeurs. Il n'y a rien de vulnérable aux clients externes de l'entreprise en eux, et leur piratage par l'un des employés internes ne causera que des inconvénients internes mineurs à un certain nombre de services.
Le service de sécurité de l'information a formulé la mise en œuvre de l'analyse de code pour les vulnérabilités comme une tâche prioritaire pour ce groupe de logiciels et les développeurs - afin de créer un processus de vérification pratique intégré dans les cycles de développement.
Intégration selon le schéma standard
GitLab de deux versions différentes a été utilisé comme système de contrôle de version dans le groupe des portails et des applications mobiles.
Configurer l'intégration avec GitLab
Toutes les applications n'utilisaient pas CI / CD, et là où ce n'était pas le cas, nous avons dû insister pour l'utiliser. Parce que si vous voulez vraiment automatiser le processus de vérification du code pour les vulnérabilités (et pas seulement télécharger manuellement un lien pour l'analyse) afin que le système lui-même le télécharge dans le référentiel et donne lui-même les résultats aux spécialistes nécessaires, vous ne pouvez pas vous passer d'installer des coureurs. Les coureurs dans ce cas sont des agents qui contactent automatiquement les systèmes de contrôle de version, téléchargent le code source et l'envoient à Solar appScreener pour analyse.
Les développeurs du portail et du groupe d'applications mobiles voulaient organiser le développement sécurisé sous la forme d'un processus semi-automatisé afin que le code soit scanné à la recherche de vulnérabilités sans aucune implication de leur part. Pour que le responsable de la sécurité vérifie les résultats de l'analyse des vulnérabilités et attribue des tâches aux développeurs dans Jira s'il considère que les vulnérabilités sont critiques, ou les envoie aux développeurs pour clarification. Les développeurs décideraient s'ils ont besoin de corriger la vulnérabilité de toute urgence ou non. Et si nécessaire, nous planifierons dans quelle version ils peuvent inclure les correctifs.
Jira était principalement utilisé comme outil de suivi des bogues, dans lequel l'analyseur de code fournissait automatiquement des informations sur les vulnérabilités trouvées.
Configuration de l'intégration Jira
Dans de rares cas, les chefs d'équipe ont examiné eux-mêmes les résultats de l'exploration et ont démarré manuellement les tâches dans Jira.
Création d'une tâche dans Jira
Nous avons également enregistré de tels cas dans la réglementation en tant que fonction distincte. Dans certains projets, en général, toutes les corrections ont été discutées dans Slack ou Telegram, et les tâches ont été définies en temps réel.
En conséquence, le processus de développement sécurisé après la mise en œuvre de Solar appScreener a commencé à ressembler à ceci: les portails sont vérifiés quotidiennement pour les changements dans le code de la branche de développement principale. Si la branche principale la plus pertinente n'a pas été mise à jour dans les 24 heures, rien ne se passe. Si elle a été mise à jour, cette branche est envoyée pour analyse au projet correspondant pour ce référentiel. Le référentiel dans GitLab correspondait à un projet spécifique dans l'analyseur de code, et c'est dans ce projet que la branche principale a été analysée. Après cela, le responsable de la sécurité a examiné les résultats de l'analyse, les a vérifiés et a commencé les tâches de correction dans Jira.
Résultats d'analyse et tâches de correction de vulnérabilité créées dans Jira
En règle générale, nous avons commencé à corriger les vulnérabilités à partir des vulnérabilités critiques, qui devaient être éliminées de toute urgence. Lorsque ces vulnérabilités ont pris fin, l'équipe a procédé à la correction des nouvelles erreurs trouvées dans le code. Et déjà à la troisième étape, par exemple, dans le cadre de la clôture de certaines dettes techniques, les anciennes vulnérabilités restantes ont également été éliminées.
Non standard en standard
Ce processus, à première vue, pas si compliqué avait deux limites sérieuses. Tout d'abord, pour analyser les applications Android (c'est-à -dire écrites en Java), nous avions besoin d'un assemblage. Et deuxièmement, iOS avait besoin de machines macOS sur lesquelles notre agent serait installé et il y aurait un environnement qui nous permettrait de créer des applications. Nous avons traité des applications Android tout simplement: nous avons écrit nos parties dans les scripts déjà disponibles pour les développeurs, qui ont également été lancés selon le calendrier. Nos parties des scripts ont pré-lancé la construction du projet dans la configuration la plus large, qui a été envoyée à Solar appScreener pour analyse. Pour vérifier les applications iOS, nous avons installé notre agent MacOS sur une machine Mac, qui a assemblé le code et a également envoyé le code à l'analyseur pour numérisation via GitLab CI. De plus, comme dans le cas d'autres types de logiciels,l'agent de sécurité a examiné les résultats de l'analyse, les a vérifiés et a soumis les problèmes de résolution à Jira.
Nous avons également fait référence aux portails et aux applications mobiles comme à tous les projets écrits en Java - nous les avons collectés et analysés de la même manière.
Dans les projets où il n'y avait pas de CI / CD, ce qui était une condition préalable pour nous, nous avons simplement dit: «Les gars, si vous voulez analyser, récupérez-le manuellement et chargez-le vous-même dans le scanner. Si vous n'avez pas de langages de type Java ou JVM - Scala, Kotlin et autres, vous pouvez simplement télécharger le code dans le référentiel à partir du lien, et tout ira bien. "
Complexité du projet
Comme vous pouvez le voir ci-dessus, dans cette pile d'applications, le principal problème était le manque de CI / CD dans de nombreux projets. Les développeurs faisaient souvent des builds à la main. Nous avons commencé à intégrer notre analyseur aux portails Sharepoint en C #. Maintenant, C # est plus ou moins passé aux systèmes Linux, bien que pas tout à fait à part entière. Et lorsque le projet battait son plein, ce langage fonctionnait toujours sous Windows, et nous avons dû installer un agent sur Windows pour GitLab. C'était un vrai défi car nos spécialistes sont habitués à utiliser les commandes Linux. Des solutions spéciales étaient nécessaires, par exemple, dans certains cas, il était nécessaire de spécifier le chemin complet du fichier exe, dans certains - non, quelque chose devait être échappé, etc. Et après la mise en œuvre de l'intégration avec Sharepoint, l'équipe du projet d'application mobile en PHP a déclaré,qu'ils n'ont pas non plus de coureur et qu'ils veulent utiliser C #. J'ai dû répéter les opérations pour eux.
Résumé
Ainsi, malgré un parc aussi hétérogène de technologies, d'équipes et de processus, nous avons réussi à regrouper les principaux cas de cette affaire en plusieurs pipelines, à automatiser leur exécution, le cas échéant, et à les mettre en œuvre. Dans notre exemple, nous avons pu nous assurer que:
- La solution que nous mettons en œuvre est suffisamment ancienne pour offrir la flexibilité dont vous avez besoin pour créer des processus DevSecOps dans des environnements de déploiement radicalement différents. La flexibilité est obtenue grâce à un vaste ensemble d'intégrations intégrées et personnalisées, sans lesquelles les coûts de main-d'œuvre pour la mise en œuvre augmenteraient considérablement ou la rendraient impossible;
- . 3-4 ;
- DevSecOps DevOps , , . win-win - .
Rappel: il s'agit de la première partie d'une série d'articles sur la mise en place d'un processus de développement sécurisé dans une grande distribution. Dans le prochain billet, nous vous dévoilerons les détails de l'implémentation de ce projet dans la famille d'applications SAP.
Avez-vous votre propre expérience dans la mise en œuvre de projets similaires? Nous serons ravis que vous partagiez avec nous vos cas d'implémentation de pratiques de développement sécurisé dans les commentaires!
Auteur: Ivan Staroselsky, chef du département d'exploitation et d'automatisation des systèmes d'information