【问题标题】:Erlang and SQL Injection Attacks [duplicate]Erlang 和 SQL 注入攻击 [重复]
【发布时间】:2013-02-14 06:49:27
【问题描述】:

我每天都使用 erlang 应用程序中间件处理 Oracle 和 MySQL 数据库。在这些中间件应用程序中,我正在运行 Nitrogen Web Framework 和 Yaws Web Server 以及几个 erlang 应用程序,例如 RabbitMQ。尽管这些应用程序容易受到SQL injection 的攻击,但它们在受信任的 Intranet 中运行。

诸如此处记录的攻击:http://sqlzoo.net/hack/ 非常能够使这些应用程序无用。是否有一个库(Erlang)或我可以如何防止这些攻击的技术?我知道在 PHP 等其他语言中,通过转义用户或攻击者可能插入的任何 single-quotes,确保所有参数都是 stringified。

说到字符串参数中的escaping all single-quotes,我想出了一个replace_all 函数,但它似乎不能解决我的需求,因为我想我会找到一种方法将所有single-quotes (') 替换为escaped version of themselves (\')。

替换(字符,带,字符串)-> 替换(字符,带,字符串,[])。
替换(_,_,[],完成)-> 列表:反向(完成); 替换(Char,With,[Char|Rest],Buffer)-> 替换(字符,带,休息,[带|缓冲区]); 替换(Char,With,[Any|Rest],Buffer)-> 替换(字符,With,Rest,[Any|Buffer])。 在几个例子上测试它:
3> sql_protect:replace($m,$k,"muzaaya")。
“库扎亚”
4> sql_protect:replace($a,$u,"muzaaya")。
“沐足”
5>
但是我如何使用这个函数来转义所有的单引号。要说String = "' OR 1=1'",改为:String = "\' OR 1=1\'"。

非常感谢您的帮助。

编辑
您对此有何看法:如果我在一个列表中有一个包含所有ORACLE SQL KEYWORDS 和SQL SERVER KEYWORDS 和MYSQL KEYWORDS 的列表,并且对于每个查询参数,我将其拆分为单词(即如果它包含空格),然后我检查以确保没有这些包含的字是保留字,我会防止许多 sql 注入攻击。

似乎有更好的方法。

【问题讨论】:

  • Erlang 不能做准备好的语句? o.0
  • 是的,不要编写自己的转义函数——改用 SQL 查询参数。使用参数,您不会将不受信任的输入插入到 SQL 中,因此您不必担心转义任何内容。我不知道 Erlang,但在 Google 上快速搜索“erlang sql parameters”会发现很多参考资料。
  • 我有点使用ODBC 与数据库通信。我还没有找到通过ODBC 使用prepared statements 的方法。至少对于 Mysql 这可能是可能的。但我与 oracle 通信的唯一方法是通过 ODBC 连接发送 SQL 语句。谢谢各位
  • 如果您使用的是 Erlang odbc 库,您要查找的函数是 param_query。

标签: mysql sql-server oracle erlang


【解决方案1】:

您不仅需要转义',还需要转义\、\0 等特殊符号。所以引用函数看起来像(从我们的 mysql 驱动程序中获取):

quote(String) when is_list(String) ->
    [39 | lists:reverse([39 | quote(String, [])])]; %% 39 is $'
quote(Bin) when is_binary(Bin) ->
    list_to_binary(quote(binary_to_list(Bin))).

quote([], Acc) ->
    Acc;
quote([0 | Rest], Acc) ->
    quote(Rest, [$0, $\\ | Acc]);
quote([10 | Rest], Acc) ->
    quote(Rest, [$n, $\\ | Acc]);
quote([13 | Rest], Acc) ->
    quote(Rest, [$r, $\\ | Acc]);
quote([$\\ | Rest], Acc) ->
    quote(Rest, [$\\ , $\\ | Acc]);
quote([39 | Rest], Acc) ->        %% 39 is $'
    quote(Rest, [39, $\\ | Acc]); %% 39 is $'
quote([34 | Rest], Acc) ->        %% 34 is $"
    quote(Rest, [34, $\\ | Acc]); %% 34 is $"
quote([26 | Rest], Acc) ->
    quote(Rest, [$Z, $\\ | Acc]);
quote([C | Rest], Acc) ->
    quote(Rest, [C | Acc]).

【讨论】:

  • 我可以将它与检查提供的参数是否包含攻击者可能注入的SQL保留字结合起来,或者这个函数足以确保即使注入保留字,数据库将被视为一个值,而不是 SQL 语句的一部分?
  • 你应该使用这个函数来编码你想要插入到查询中的任何字符串参数。如您所见,它在参数周围添加了引号,因此里面的所有内容都将被解析为字符串。所以您不必担心关键字。
  • 我还发现要转义 oracle 单引号,您需要另一个单引号,所以它们变成了两个。
【解决方案2】:

我不了解 erlang 库,但我假设您可以创建 prepared statements,它在执行时会自动“清理”您的字符串。这甚至是 php 领域的首选方法,带有 PDO 和 mysqli。不推荐使用 escape_strings 和 mysql 驱动程序。

【讨论】:

  • erlang 不是 php的方言
  • 从来没有说过。原贴引用了php,所以我又引用了php
猜你喜欢
  • 2013-04-13
  • 1970-01-01
  • 2015-10-03
  • 2019-08-10
  • 2019-08-20
  • 2013-05-21
  • 2013-08-15
  • 1970-01-01
  • 2021-12-11
相关资源
最近更新 更多