如何避免在tcl脚本中使用的javascript中的跨站点脚本?

时间:2014-05-29 10:19:05

标签: javascript open-source tcl xss sql-injection

在开放项目开放(开源应用程序)时,网址http://[host_ip]:8000/register/包含易受跨网站脚本攻击的Java脚本使用SQL注入进行身份验证绕过

我想知道我该如何避免它?我必须为此插入过滤器吗?我应该怎么做?

如果问题不明白,请告诉我。

1 个答案:

答案 0 :(得分:0)

SQL注入

SQL注入问题的通用答案是“永远不会将任何用户输入作为SQL字符串的一部分发送到数据库”。任何可以作为参数的东西都应该这样做。因此,而不是(在一些方言中可能与你正在看的东西不完全匹配):

db eval "SELECT userid FROM users WHERE username = '$user' AND password = '$pass'"
你这样做:

db eval "SELECT userid FROM users WHERE username = ? AND password = ?" $user $pass
# I personally prefer to put SQL inside {braces}… but that's your call

关键是,因为数据库引擎只知道这些是参数,所以它永远不会尝试将它们解释为SQL。 无法注入。(除非您使用写得不好的存储过程。)

如果您希望用户指定表或列名称,则会变得更加复杂。这是您无法将其作为参数发送的情况; SQL引擎必须解释此类SQL标识符必须。您唯一的选择是从用户提供的术语重新映射到您控制的术语,或者严格验证。

通过使用一个单独的简单表来完成重新映射,该表从用户提供的名称映射到您已生成的名称:

db eval {SELECT realname FROM namemap WHERE externalname = ?} $externalname

因为生成的名称很容易保证没有令人讨厌的字符而不是SQL关键字之一,所以可以安全地在SQL文本中使用它而无需进一步引用。您还可以尝试通过从中删除所有不良字符来按请求执行映射(将映射代码分解为过程)。合适的regsub可能是:

regsub -all {\W+} $externalname "" realname

然后我们需要额外的检查才能看出它不是“邪恶的”:

# You'll need to create an array, SQLidentifiers, first, perhaps like:
#    array set SQLidentifers {UPDATE - SELECT - REPLACE - DELETE - ALTER - INSERT -}
# But you can do that once, as a global "constant"
if {[regexp {^\d} $realname] || [info exist SQLidentifiers([string toupper $realname])]} {
    error "Bad identifier, $externalname"
}

正如您所看到的,将这些转换和检查纳入自己的程序是一个好主意,这样您就可以正确一次

必须广泛测试您的代码 。我不能强调这一点。您的测试必须尝试非常难以破解,通过任何人可以传递到软件中的每个可能字段进行SQL注入;其中没有一个应该导致你的代码所期望的任何事情发生。

让其他人至少写一些测试可能是个好主意;安全社区的经验表明编写代码是相对容易的,你可以自己打破,但编写其他人无法破解的代码要困难得多。还要考虑进行模糊测试,在接口上发送计算机生成的随机数据。在所有情况下,任何事情都应该给出一个优雅的错误或应该成功,但永远不会导致应用程序完全失败。

(您可能允许经过高度身份验证的用户 - 系统/数据库管理员 - 直接指定要评估的SQL,以便他们可以执行诸如设置系统之类的操作,但它们是少数情况。)

跨站点脚本

这实际上在概念上非常相似:它(主要)由某人在您的网站中放置某些内容而意外地被解释为HTML(或CSS或Javascript)而不是人类可读的文本(使用SQL注入) ,它被解释为SQL而不是数据。因为在返回客户端时您无法进行参数化查询,所以必须谨慎引用。强烈建议您使用构造DOM树的适当模板库(来自用户或来自数据库的数据仅作为文本节点插入)来进行仔细引用。 / p>

如果您希望用户提供标记的文本,请考虑在使用Javascript将其呈现为Markdown之前将其作为纯文本传回,或者在服务器上完全解析用户提供的文本以构建模型(例如,DOM树)应该传递什么,然后再将其作为从该模型生成的HTML发回。

不得允许用户指定从中加载脚本或框架的位置。即使允许他们指定链接也令人担忧,但如果您不能将内容限制为直接纯文本,则可能必须允许这样做。 (考虑添加用于列出用户提供的所有链接的机制。考虑使用rel=nofollow标记所有外部链接,除非您可以肯定地检测到它们会转到您列入白名单的位置。)

直接提供HTML是“仅经过高度身份验证的用户”操作。

(我在上面说谎。你可以做相当于SQL参数化的查询。你编写了客户端执行的JS,用AJAX查询获取用户数据,可能被序列化为JSON,并且然后在那里进行DOM操作来渲染它;实际上,你将DOM结构从服务器移动到客户端,但你仍然在进行DOM构建,因为这是你获得的核心这是正确的。你必须记住从不插入检索为直接HTML的内容。客户端不能过多地信任服务器。)

我上面提到的关于 测试 的评论也适用于此。通过XSS测试,您需要注入类似<script>alert("boom!")</script>的内容;任何时候你都可以进入并导致弹出对话框 - 除非作为直接允许直接编辑HTML的系统管理员 - 你有一个巨大的危险漏洞。 (尝试注射是一件非常好的事情,因为它本身非常明显且相当温和。)

请勿尝试使用正则表达式过滤掉<script>。要做到这一点太难了。

相关问题