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

时间:2015-06-01 12:22:01

标签: php mysql pdo xss 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...

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注入? 另外如何防止拒绝服务(导致创建过多的行)?

1 个答案:

答案 0 :(得分:4)

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

所以,你正在处理“小鲍比表”就好了。

你问的是处理Bobby的堂兄:“Shifty Earl”。

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

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

当我们将“Shifty Earl”的名字放回网页时出现问题。

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

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

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

PHP有一个很棒的函数叫做 htmlentities 。 (其他语言/库具有相同的功能。)

返回:

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

将是这样的:

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

请注意,“ &lt; ”称为html实体。它表示“小于”字符,但将被解释为标记的开头。我们会通过“ &#60; ”获得相同的结果。

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

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

但是,并且将被解释为HTML标记。

如何防止XSS漏洞?

通过适当地转义所有可能不安全的值(通过用等效的html实体替换HTML标记字符),当这些值合并到网页中时(在准备将网页发送到客户端时)。< / p>

数据库真的与它无关。

当我们在数据库中存储字符串时,我们不进行“htmlentities”转义的原因是它不适合这样做。

有人在查看你的代码时会看到一个可能不安全的值被放到网页上,并且会在它放到页面之前添加相应的htmlentities函数。然后我们将进行双重转义,再次对值进行编码。

当将值放在网页上时,正确执行转义的地方是

还有其他可能不安全的值来源,从文件读取的值,从其他表中读取的值,或用户在Web表单上提供的值。如果代码假设某个特定表中某个特定列的值是“安全的”,并且来自其他来源的值不安全,则会很难。

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