{"id":5666,"date":"2023-01-19T12:26:10","date_gmt":"2023-01-19T11:26:10","guid":{"rendered":"https:\/\/www.vaadata.com\/blog\/?p=5666"},"modified":"2023-01-19T19:17:12","modified_gmt":"2023-01-19T18:17:12","slug":"orm-exploitation-relations-en-cascade-et-defaut-de-validation-entrees-utilisateur","status":"publish","type":"post","link":"https:\/\/www.vaadata.com\/blog\/fr\/orm-exploitation-relations-en-cascade-et-defaut-de-validation-entrees-utilisateur\/","title":{"rendered":"ORM : exploitation relations en cascade et d\u00e9faut de validation entr\u00e9es utilisateur"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignright size-medium\"><img decoding=\"async\" width=\"300\" height=\"157\" src=\"https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2023\/01\/ORM_exploitation_relations_cascade-300x157.png\" alt=\"ORM : exploitation relations en cascade et d\u00e9faut de validation entr\u00e9es utilisateur\" class=\"wp-image-5713\" srcset=\"https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2023\/01\/ORM_exploitation_relations_cascade-300x157.png 300w, https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2023\/01\/ORM_exploitation_relations_cascade-1024x535.png 1024w, https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2023\/01\/ORM_exploitation_relations_cascade.png 1200w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/figure>\n<\/div>\n\n\n<p>En 2021, le top 10 de l&rsquo;OWASP, qui met en lumi\u00e8re les vuln\u00e9rabilit\u00e9s les plus courantes des applications, a quelque peu \u00e9volu\u00e9. En effet les failles d\u2019injection, auparavant les plus critiques, se retrouvent d\u00e9sormais sur la troisi\u00e8me marche du podium.<\/p>\n\n\n\n<p>Cela peut s&rsquo;expliquer notamment par le fait que les d\u00e9veloppeurs prennent davantage conscience des risques li\u00e9s aux vuln\u00e9rabilit\u00e9s d\u2019injections via la mise en \u0153uvre d&rsquo;outils et de pratiques plus s\u00fbrs pour le d\u00e9veloppement d\u2019applications. Et \u00e9videmment LA mesure essentielle pour limiter le risque d&rsquo;<a href=\"https:\/\/www.vaadata.com\/blog\/fr\/injections-sql-principes-impacts-exploitations-bonnes-pratiques-securite\/\" target=\"_blank\" rel=\"noopener\" title=\"\">injection SQL<\/a> consiste en l\u2019utilisation de requ\u00eates pr\u00e9par\u00e9es. <\/p>\n\n\n\n<p>Pour ce faire, on utilise g\u00e9n\u00e9ralement un <strong>ORM<\/strong>, ce qui peut introduire de nouveaux risques comme nous allons le voir dans cet article. <\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Qu\u2019est-ce qu\u2019un ORM ?&nbsp;<\/h2>\n\n\n\n<p>La plupart des applications ont besoin de manipuler et de stocker des donn\u00e9es. Pour ce faire et pour faciliter leur travail, les d\u00e9veloppeurs peuvent avoir recours \u00e0 des ORM (Object-Relational Mapping), qui permettent de g\u00e9rer l&rsquo;acc\u00e8s \u00e0 une base de donn\u00e9es de mani\u00e8re s\u00e9curis\u00e9e (en th\u00e9orie). <\/p>\n\n\n\n<p>En effet, un ORM consiste en un ensemble de classes et de m\u00e9thodes permettant de manipuler les tables d\u2019une base de donn\u00e9es relationnelle comme des objets. <\/p>\n\n\n\n<p>Ici, nous allons nous int\u00e9resser \u00e0 TypeORM, un ORM pour TypeScript et JavaScript. Le d\u00e9veloppeur \u00e9crira alors des mod\u00e8les qui pourront \u00eatre en relation les uns avec les autres. Ce qui nous int\u00e9resse, ce sont les propri\u00e9t\u00e9s des relations entre deux mod\u00e8les, notamment celles de cascade.<\/p>\n\n\n\n<p>Si cette propri\u00e9t\u00e9 est d\u00e9finie comme \u00e9tant vraie entre deux entit\u00e9s, alors mettre \u00e0 jour un c\u00f4t\u00e9 de la relation et faire la sauvegarde sur l\u2019autre mettra \u00e0 jour les deux c\u00f4t\u00e9s dans la base de donn\u00e9es, et pourra m\u00eame cr\u00e9er de nouveaux objets.<\/p>\n\n\n\n<p>Cependant, comme indiqu\u00e9 dans la <a href=\"http:\/\/typeorm.io\/relations#cascades\" target=\"_blank\" rel=\"noopener\" title=\"\">documentation des cascades<\/a>, ces derni\u00e8res peuvent sembler \u00eatre un moyen simple et efficace de travailler avec des relations, mais elles peuvent \u00e9galement \u00eatre \u00e0 l&rsquo;origine de bugs et de probl\u00e8mes de s\u00e9curit\u00e9. De plus, elles constituent un moyen moins explicite d&rsquo;enregistrer de nouveaux objets dans la base de donn\u00e9es.<\/p>\n\n\n\n<p>Cela n\u2019emp\u00eache cependant pas les d\u00e9veloppeurs de les utiliser. Il faut dire que c\u2019est quand m\u00eame bien pratique lorsqu\u2019il y a une mise \u00e0 jour de plusieurs entit\u00e9s en relation de n\u2019avoir \u00e0 en sauvegarder qu\u2019une seule pour sauvegarder les autres.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sc\u00e9nario d&rsquo;exploitation des relations en cascade avec un d\u00e9faut de validation des entr\u00e9es utilisateurs  <\/h2>\n\n\n\n<p>Int\u00e9ressons-nous \u00e0 un exemple concret, inspir\u00e9 d&rsquo;un cas rencontr\u00e9 lors d&rsquo;un <a href=\"https:\/\/www.vaadata.com\/fr\/pentest-web\/\" title=\"\">pentest d&rsquo;application web<\/a>.<\/p>\n\n\n\n<p>Il est commun pour des applications de s\u00e9parer la gestion de chaque ressource et d\u2019impl\u00e9menter des tests de s\u00e9curit\u00e9 \u00e0 l\u2019endroit qui correspond.<\/p>\n\n\n\n<p>On peut donc imaginer une application avec des utilisateurs et des documents associ\u00e9s.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ts \n@Entity()\nclass User {\n        @PrimaryGeneratedColumn()\n        id!: number\n\n        @Column()\n        name!: string\n\n        @Column({ default: false })\n        admin!: boolean\n}\n\n@Entity() \nclass Document {\n        @PrimaryGeneratedColumn()\n        id!: number\n\n        @Column()\n        content!: String\n\n        @Column()\n        authorId!: number\n\n        @OneToOne(() =&gt; User, { cascade: true })\n        @JoinColumn()\n        author!: User\n}<\/code><\/pre>\n\n\n\n<p>Comme on peut le voir, les deux ressources sont reli\u00e9es gr\u00e2ce \u00e0 la relation <code>OneToOne<\/code> sur <code>Document<\/code> qui a la particularit\u00e9 d\u2019\u00eatre en cascade.<\/p>\n\n\n\n<p>On peut d\u00e9sormais imaginer que chaque ressource poss\u00e8de son propre contr\u00f4leur.<\/p>\n\n\n\n<p>Par exemple, celui pour les utilisateurs pourrait permettre la lecture de n\u2019importe quelle ressource, mais limiter la mise \u00e0 jour de champs prot\u00e9g\u00e9s (comme les r\u00f4les par exemple) ou plus simplement ne pas permettre la mise \u00e0 jour d\u2019un utilisateur.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ts\napp.get(\"\/user\", async (_request, reply) =&gt; {\n        reply.send(await users.findOneBy({ id: 1 }))\n})<\/code><\/pre>\n\n\n\n<p>Alors que le contr\u00f4leur de la ressource associ\u00e9e serait un peu plus permissif en permettant la mise \u00e0 jour de tous les champs en prenant directement l\u2019entr\u00e9e de l\u2019utilisateur et la sauvegarderait directement en base de donn\u00e9es.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ts\napp.get(\"\/document\", async (_request, reply) =&gt; {\n        reply.send(await documents.findOneBy({ id: 1 }))\n})\n\napp.put(\"\/document\", async (request, reply) =&gt; {\n        const result = { ...request.body as any, id: 1 }\n        reply.send(await documents.save(result))\n})<\/code><\/pre>\n\n\n\n<p>Ici, si on jette un coup d\u2019\u0153il \u00e0 notre application, il est possible de r\u00e9cup\u00e9rer un utilisateur.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/user\n\n{\"id\":1,\"name\":\"Dummy user\",\"admin\":false}\n<\/code><\/pre>\n\n\n\n<p>Il est aussi possible de r\u00e9cup\u00e9rer le document qui lui est associ\u00e9.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/document\n\n{\"id\":1,\"content\":\"My document content!\",\"authorId\":1}\n<\/code><\/pre>\n\n\n\n<p>Et aussi de mettre \u00e0 jour ce document.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PUT \/document\n\n{\"content\":\"Modified content\"}\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/document \n\n{\"id\":1,\"content\":\"Modified content\",\"authorId\":1}\n<\/code><\/pre>\n\n\n\n<p>Cependant, la fonctionnalit\u00e9 de mise \u00e0 jour du document devient vuln\u00e9rable \u00e0 cause de la propri\u00e9t\u00e9 cascade de la relation. En effet, un attaquant pourrait lors de la mise \u00e0 jour du document mettre aussi \u00e0 jour l\u2019utilisateur associ\u00e9 en le mettant administrateur par exemple, ce qui n\u2019aurait pas \u00e9t\u00e9 possible avec le contr\u00f4leur de l\u2019utilisateur.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PUT \/document\n\n{\"content\":\"Modified content\",\"author\":{\"id\":1,\"admin\":true}}<\/code><\/pre>\n\n\n\n<p>En faisant cette requ\u00eate l\u2019attaquant va ajouter l\u2019objet utilisateur qui correspond \u00e0 l\u2019auteur du document, en sauvegardant le document, l\u2019utilisateur associ\u00e9 sera aussi sauvegard\u00e9 \u00e0 cause de la propri\u00e9t\u00e9 cascade.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/user\n\n{\"id\":1,\"name\":\"Dummy user\",\"admin\":true}<\/code><\/pre>\n\n\n\n<p>En regardant l\u2019utilisateur, nous voyons que ses propri\u00e9t\u00e9s ont bien \u00e9t\u00e9 mises \u00e0 jour.<\/p>\n\n\n\n<p>Pour pr\u00e9venir ce type de risques, il est recommand\u00e9 d\u2019\u00e9viter les relations en cascade, mais encore plus important, de bien v\u00e9rifier ce qui est envoy\u00e9 par l\u2019utilisateur. En effet, l\u2019objet pour l\u2019auteur n\u2019aurait jamais d\u00fb \u00eatre pr\u00e9sent lors de la sauvegarde de la ressource, il aurait fallu filtrer les propri\u00e9t\u00e9s autoris\u00e9es.<\/p>\n\n\n\n<p><strong>Conclusion<\/strong><\/p>\n\n\n\n<p>L&rsquo;utilisation d&rsquo;ORM peut \u00eatre tr\u00e8s utile afin de r\u00e9duire le risque d\u2019injection ainsi que le temps de d\u00e9veloppement et de maintenance des applications. Cependant, cette pratique peut \u00e9galement entra\u00eener des probl\u00e8mes de s\u00e9curit\u00e9 si elle est mal g\u00e9r\u00e9e. Une bonne pratique est d&rsquo;utiliser des propri\u00e9t\u00e9s de cascade avec prudence et de bien contr\u00f4ler les entr\u00e9es des utilisateurs afin de s&rsquo;assurer que seules les donn\u00e9es autoris\u00e9es sont sauvegard\u00e9es.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Auteur : Arnaud PASCAL \u2013 Pentester @Vaadata<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En 2021, le top 10 de l&rsquo;OWASP, qui met en lumi\u00e8re les vuln\u00e9rabilit\u00e9s les plus courantes des applications, a quelque peu \u00e9volu\u00e9. En effet les failles d\u2019injection, auparavant les plus critiques, se retrouvent d\u00e9sormais sur la troisi\u00e8me marche du podium. Cela peut s&rsquo;expliquer notamment par le fait que les d\u00e9veloppeurs prennent davantage conscience des risques<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":{"0":"post-5666","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-technique"},"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/5666","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/comments?post=5666"}],"version-history":[{"count":27,"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/5666\/revisions"}],"predecessor-version":[{"id":5716,"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/5666\/revisions\/5716"}],"wp:attachment":[{"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/media?parent=5666"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/categories?post=5666"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/fr\/wp-json\/wp\/v2\/tags?post=5666"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}