使用 PHP 在一个字符串中搜索多个标记的最有效方法是啥?

Posted

技术标签:

【中文标题】使用 PHP 在一个字符串中搜索多个标记的最有效方法是啥?【英文标题】:What is the most efficient way to search for multiple tokens in one string using PHP?使用 PHP 在一个字符串中搜索多个标记的最有效方法是什么? 【发布时间】:2014-05-01 16:28:41 【问题描述】:

我们希望检查所有传入的 GET/POST 数据是否存在恶意代码。如果检测到,我们希望从服务器发出禁令。虽然搜索了所有数据,但我有点担心性能。

使用 php,我们目前正在做这样的事情:

$t = $_POST['example'];
if(
    (strpos($t, 'hex') && strpos($t, 'unhex')) || 
    (strpos($t, 'etc') && strpos($t, 'passwd')) || 
    strpos($t, 'information_schema')
  )
  // Initiate ban of IP

有没有更有效的方法来做到这一点?目标是不将资源浪费在“错误请求”上。我们使用准备好的语句,所以这是一个性能问题而不是安全问题。黑名单发生在瞻博网络级别,这意味着数据库服务器、文件服务器等在最初的错误请求后完全不会紧张。

仅供参考:像 OSSEC 这样的程序在抽签上太慢了。他们通常允许处理 20-40 个请求,然后才真正做出反应并开始禁止过程。在应用层,我们可以捕获第一个请求。这似乎无关紧要,但是当您受到 100 多个 IP 地址的攻击时,捕获第一个请求会产生巨大的差异。

【问题讨论】:

我不会打扰。 IP禁令很容易避免。只要您使用准备好的语句就可以了,DOOS 保护应该在服务器后端的服务器端完成。 我不是在编写像 Stack Overflow 这样的信息交换应用程序。如果我是,我会寻找不同的解决方案。我们所处的环境中,年轻人喜欢尝试经常使服务器紧张的恶意攻击。 您似乎正在尝试使用黑名单方法来确保安全。请注意,这永远不会奏效。 “坏东西”几乎有无数种变体,您无法将它们全部过滤掉。 如果检查每个请求的成本高于允许 20-40 个请求通过未经检查的情况,则后者可能是更好的选择。你永远无法阻止攻击,你只能尝试限制伤害。用众所周知的脚射击自己似乎不是一个好主意。 Hey Halcyon -- 好建议,但速率限制很困难。许多访问我们信息的大学都来自一个 IP 地址。如果一个班级的学生要同时访问该网站,他们都会在一个 IP 地址下注册。 【参考方案1】:

您所做的是将您可能通过表单收到的某些表达方式列入黑名单。 这不是最有效的做法,因为攻击者可能会使用您没有考虑过的替代方法来绕过您的控制。

防止 sql 注入的最佳做法是根据您希望允许的内容将内容列入白名单。

以下来自Cisco website on SQL injection:

在应用程序本身内,有两种输入方法 可以防御 SQL 注入攻击的验证:黑名单 和白名单。带有黑名单、特定的、已知的恶意 从用户输入中删除或替换字符。虽然这 方法经常被实施,主要是因为它可以很容易地 完成后,与白名单相比,它是无效的。 黑名单可能无法正确处理复杂的混淆,这 可能允许攻击者破坏过滤器并可能注入 SQL 陈述。这种失败通常是由于不断演变的攻击而发生的 不全面或未实施的技术和过滤器 正确。

另外,白名单会根据 允许的字符列表。这种方法在 降低 SQL 注入的风险,因为它更具限制性 关于允许输入的类型。执行良好 白名单应该检查每一条用户提供的数据 预期的数据格式。

根据您使用的方法类型和您希望接收的数据类型,您将有不同的性能来检查 SQL 注入。

【讨论】:

同样,这不是一个安全问题,而是一个性能问题。我们看到的攻击与他们的输入非常一致。它很容易检测到,与其让页面执行 5-8 个查询,我们宁愿停止/禁止以减少负载。

以上是关于使用 PHP 在一个字符串中搜索多个标记的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在巨大列表中查找/搜索的最有效方法(python)

在数据库中存储标签的最有效方法是什么?

在多个表上进行条件 mysql 连接的最有效方法? (Yii php 框架)

实现语音搜索的最有效方法

在字符串中搜索未知模式的最有效方法?

使用 PHP 的多个谷歌地图标记