如何防止 XSS 攻击 (php/pdo)

Mon*_*ess 2 php mysql xss pdo sql-injection

我有函数,首先:JS:

    $(document).ready(function() {

        //dodavanje novog racuna
       $(function() { 
        $('#addFieldForm').submit(function(e) { 
            e.preventDefault();

            if ( $(this).parsley('validate') ) {

            $.ajax({
                url: "insertRacun.php",
                type: "POST",
                async: true, 
                data: { sifra:sifra,brojracuna:$("#brojracuna").val(),sufiks:$("#sufiks").val(),kupac:$("#kupac").val(),adresa:$("#adresa").val(),grad:$("#grad").val(),pib:$("#pib").val(),total:$("#total").text(),valuta:$("#valuta").val(),nacin:$("#nacin").val(),datum:$("#datum").val(),rok:$("#rok").val(),isporuka:$("#isporuka").val(),napomena:$("#napomena").val(),interna:$("#interna").val(),ponovi:$("#ponovi").val()},           
                dataType: "html",
etc...
Run Code Online (Sandbox Code Playgroud)

php:

try {        
                $STH = $db->prepare("INSERT INTO racuni (br, sufiks, kupac, adresa, grad, pib, total,valuta,nacin,datum,rok,isporuka,napomene,interne, user_id,sifra) VALUES (:0,:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15)");
                $STH->bindParam(':0', $_POST['brojracuna']);
                $sufiks=$_POST['sufiks'];
                $STH->bindParam(':1', $sufiks);
        $STH->bindParam(':2', $_POST['kupac']);
                $STH->bindParam(':3', $_POST['adresa']);
etc....
Run Code Online (Sandbox Code Playgroud)

当我尝试添加时:

Luciansdasadsda"><script>alert(1)</script>
Run Code Online (Sandbox Code Playgroud)

然后我在数据库中获得相同的值。

那么如何在我的代码中防止 XSS 和 SQL 注入呢?还如何防止拒绝服务(导致创建过多的行)?

spe*_*593 7

OWASP 跨站点脚本 (XSS) 预防备忘单
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet


您传递给数据库的字符串值被存储在数据库中。这是预期的行为。MySQL、PDO 或带有绑定占位符的准备好的语句中没有任何内容旨在防止存储看起来像 javascript 的字符串。

这一切都是为了防止恶意字符串被解释为 SQL 语句的一部分,ala XKCD Exploits of a Mom https://xkcd.com/327/

  Robert'; DROP TABLE students; --
Run Code Online (Sandbox Code Playgroud)

因此,您可以很好地处理“Little Bobby Tables”。

你问的是如何处理鲍比的堂兄:“狡猾的伯爵”。

  <script>alert('hello')</script>
Run Code Online (Sandbox Code Playgroud)

我们可以将 Shifty Earl 的名字插入到表中就好了;没有可以阻止的恶意 SQL 注入。

当我们将“Shifty Earl”的名字重新显示在网页上时,问题就来了。

我们必须将他的名字视为可能不安全(就像我们对 Little Bobby Tables 所做的那样)。

在这里,将它放在网页上是不安全的,除非我们正确地逃脱它。

那么,我们如何逃避它以使其安全显示?

PHP 有一个漂亮的函数,叫做htmlentities. (其他语言/库具有等效功能。)

回报来自:

 htmlentities("<script>alert('hello')</script>") 
Run Code Online (Sandbox Code Playgroud)

将是这样的:

 &lt;script&gt;alert('hello')&lt;/script&gt;
Run Code Online (Sandbox Code Playgroud)

请注意,“ &lt;” 称为 html 实体。它代表一个“小于”字符,但不会被解释为标签的开始。我们会得到与“ &#60;”相同的结果。

当我们将转义/编码的字符串放在网页上时,浏览器显示的内容看起来像原始字符串......

 <script>alert('hello')</script>
Run Code Online (Sandbox Code Playgroud)

但是,这不是不会被解释为 HTML 标签。

你如何防止 XSS 漏洞?

通过正确转义所有潜在的不安全值(通过用等效的 html 实体替换 HTML 标记字符),当这些值被合并到网页中时(在网页准备发送给客户端时)。

数据库真的与它无关。

当我们在数据库中存储字符串时,我们不执行“htmlentities”转义的原因是它不是执行此操作的正确位置。

查看您的代码的人会看到一个潜在的不安全值被放置到网页上,并将在htmlentities那里添加适当的函数,或者在它被放置到页面之前。然后我们会得到双重转义,第二次对值进行编码。

值放在网页上,进行转义的正确位置是正确的。

还有其他潜在不安全值的来源、从文件、其他表中读取的值或用户在 Web 表单上提供的值。如果代码假设来自特定表中特定列的值是“安全的”,而来自其他来源的值不安全,那将是不可靠的。


OWASP SQL 注入
https://www.owasp.org/index.php/SQL_Injection

OWASP 跨站点脚本 (XSS) 预防备忘单
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet