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

How to prevent XSS attack (php/pdo)

我有函数,首先: 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...

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....

当我尝试添加时:

Luciansdasadsda"><script>alert(1)</script>

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

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

OWASP Cross Site Scripting (XSS) Prevention Cheat Sheet
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet


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

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

  Robert'; DROP TABLE students; --

那么,您处理 "Little Bobby Tables" 就好了。

你问的是如何处理 Bobby 的堂兄:"Shifty Earl"。

  <script>alert('hello')</script>

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

当我们将 "Shifty Earl" 的名字重新放到网页上时,问题就来了。

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

在这里,将它放在网页上是不安全的,除非我们正确地对其进行转义。

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

PHP 有一个漂亮的函数叫做 htmlentities。 (其他 languages/libraries 具有相同的功能。)

return 来自:

 htmlentities("<script>alert('hello')</script>") 

会是这样的:

 &lt;script&gt;alert('hello')&lt;/script&gt;

请注意,“&lt;”被称为 html 实体。它表示一个 "less than" 字符,但它 不会 被解释为标记的开头。我们会得到与“&#60;”相同的结果。

当我们将 escaped/encoded 字符串输出到网页上时,浏览器显示的内容看起来像原始字符串...

 <script>alert('hello')</script>

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

如何防止XSS漏洞?

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

数据库真的没关系

当我们将字符串存储在数据库中时,我们不进行 "htmlentities" 转义的原因是它不是进行转义的正确位置。

查看您的代码的人会看到将可能不安全的值放到网页上,并会在将其放到页面之前添加适当的 htmlentities 函数。然后我们将进行双重转义,对值进行第二次编码。

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

还有其他来源的潜在不安全值、从文件中读取的值、从其他 table 或用户在 Web 表单上提供的值。如果代码假设某个特定 table 中某一特定列的值是 "safe",并且其他来源的值不安全,那将是不安全的。


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

OWASP Cross Site Scripting (XSS) Prevention Cheat Sheet
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet