Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114555 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 68798 invoked from network); 21 May 2021 17:30:27 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 21 May 2021 17:30:27 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BD4301804F4 for ; Fri, 21 May 2021 10:40:46 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.7 required=5.0 tests=BAYES_05,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 21 May 2021 10:40:46 -0700 (PDT) Received: by mail-lf1-f43.google.com with SMTP id c10so9852518lfm.0 for ; Fri, 21 May 2021 10:40:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=craigfrancis.co.uk; s=default; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=7ggeAkrPmnjo5xufBmdiXwbJRBk7Qh56/VH6wDKD4Aw=; b=DbwrJjyKawmMYoXi2p9SabwIBJclYNKEw3xU3rG7AnbmVv64zlyNR1Tvse/9YiU0Je +upcpnxf1elgVOtjkyko9VX/GQ0CvE0JbCJ/P3uoTKc20GB0Tx7IzTAn9TqvkdCklSKB llCXlPsn+D6GLjLnQRUlIp2wpGStF1DgCPfKI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=7ggeAkrPmnjo5xufBmdiXwbJRBk7Qh56/VH6wDKD4Aw=; b=HtkVfUWwURC8uO5weDVh5aOLOdRompjRGhegtXXOJZ2npQqP4/+3W60QgUIzUjgRjU A6lA+A6KWfO+p7zj+uRYiAEaDEu64ZGkz0uF/mg65wWWIIprg2V7QfhXQlB4bsV6m4hc cUtRftJqkZo51T8DhupWxtNHIte6xbsrhdGMUFrk3irnYkslj1luYsnPU/ZMVBnXNPZZ GCCh/gxGy5Qc/qpUIvtokt/h13Z1AU7v3gBkvtGY2ca1cvU4reL7RM1NF/kwYA2U/lG6 OpLHe+RpgD+nzd4WfVXAIq9q0Bmz0AhQIeM8Hn4cNbjGrcE13pV/KcPQMTlC63J+lELi dmKw== X-Gm-Message-State: AOAM532WJEGF7X5pieEhOolVGu7Rez7gFf7gSZYAEFEDSP7icH9HApf2 NZtWGqcaeHGXf5aSqKqb6F8SBBJK6eNfiA2c+6GSfsK4aKjKww== X-Google-Smtp-Source: ABdhPJxg0bM0TTCGcLQz15fygaXbFc/XnSGysxla46q3StKvfGfbuwD6agofTmZSFX6pT4EOJMQqbNdCqIqfFEN0nJE= X-Received: by 2002:a05:6512:468:: with SMTP id x8mr2874491lfd.519.1621618842206; Fri, 21 May 2021 10:40:42 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Fri, 21 May 2021 18:40:31 +0100 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="0000000000000d2d3d05c2da8f96" Subject: Re: Injection vulnerabilities From: craig@craigfrancis.co.uk (Craig Francis) --0000000000000d2d3d05c2da8f96 Content-Type: text/plain; charset="UTF-8" Hi Internals, To follow up on yesterdays post [1]... We *could* try to teach programmers to never make a mistake (yep, you can stop laughing). Take the previous example: $html = ""; We might be able to teach everyone to always quote their attributes (or use a different form of encoding): $html = ""; And before PHP 8.1 [2] is released, teach them htmlentities doesn't encode single quotes by default. And teach them about dangerous things like '', due to 'javascript:' URLs... etc, etc. The first part to solving this, use the Parameterised Queries idea from SQL - the programmer writes their HTML string, and keeps their HTML completely *separate* from the user values. To combine, they provide both to a HTML templating engine, that knows how to do appropriate escaping. For example: html("", [$url]); Which can be done today, but it doesen't stop injection mistakes from happening (the second part of this problem). It's still trivial for a programmer to mistakenly include (inject) user values into that first argument: html(""); And note how this mistake is exactly same as the other examples, and doing this with Laravel [3]: DB::select('select * from users where active = ' . $_GET['active']); // INSECURE DB::select('select * from users where active = ?', [$_GET['active']]); Craig [1] https://externals.io/message/114540 [2] https://github.com/php/php-src/commit/50eca61f68815005f3b0f808578cc1ce3b4297f0 [3] https://laravel.com/docs/8.x/database#running-a-select-query > --0000000000000d2d3d05c2da8f96--