如何绝对防止注入

前言

前不久的时候,发小 说不敢把自己的代码发到github上面,怕很多人找bug比较麻烦,我同时也在思考一个问题,平时审计或者黑盒的时候都没有留意,总是想着如何进攻别人,现在换一个角度来总结一下,如何做到百分百防止注入呢,也许从这个角度学习会让我进步更快。

一、浅谈sql注入

mysql_real_escape_string

在测试是否存在sql注入的时候,主要是看是否有可控的变量,那么在程序员的角度上,可能会用mysql_real_escape_string,是一个字符串转义函数。它将做的只是转义危险字符,以便它们可以安全地用于单个查询字符串。但是,如果您不事先清理输入,那么您将容易受到某些攻击向量的攻击。
想象一下下面的sql:

$result = "SELECT fields FROM table WHERE id = ".mysql_real_escape_string($_POST['id']);

您应该能够看到这很容易被利用。
想象一下id参数包含常见的攻击向量:

1 OR 1=1

那里没有要编码的危险字符,因此它将直接通过转义过滤器。
记录一个sql语句

1 or is_admin=1 order by id limit 1

产生

SELECT fields FROM table WHERE id=1 or is_admin=1 order by id limit 1

这允许攻击者在这个完全虚构的示例中返回第一个管理员的详细信息。

所以在使用mysql_real_escape_string这个函数拼接到sql语句时一定要加引号,把参数限制在里面

自己定义的转义函数

有些人会把所有的输入都经过验证,如定义一个函数,来检验用户输入的是否都是数字

function Numbers($input) {
  $input = preg_replace("/[^0-9]/","", $input);
  if($input == '') $input = 0;
  return $input;
}

所以不是使用

$result = "SELECT fields FROM table WHERE id = ".mysqlrealescapestring("1 OR 1=1");

他会用

$result = "SELECT fields FROM table WHERE id = ".Numbers("1 OR 1=1");

但是从功能搜索框的功能角度上来考虑,这显然有很多限制,如在csdn上面就不能使用。

PDO与MySQLi

无论您使用哪种转义方法,避免 SQL 注入攻击的正确方法是将数据与 SQL 分离,以便数据保持数据,永远不会被 SQL 解析器解释为命令。可以使用格式正确的数据部分创建 SQL 语句,但如果您不完全了解详细信息,则应始终使用准备好的语句和参数化查询。这些是与任何参数分开发送到数据库服务器并由其解析的 SQL 语句。这样攻击者就不可能注入恶意 SQL。
你基本上有两种选择来实现这一点:
1.使用PDO(对于任何支持的数据库驱动程序):

$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute([ 'name' => $name ]);

foreach ($stmt as $row) {
    // Do something with $row
}

2.使用MySQLi(用于 MySQL):

$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'
$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // Do something with $row
}

但是这个绝对依旧是有前提的,虽然利用起来相对苛刻,还是提一下吧

  • 使用 MySQL 的现代版本(5.1 后期,所有 5.5、5.6 等)和PDO 的 DSN 字符集参数(在 PHP ≥ 5.3.6 中)
  • 不要使用易受攻击的字符集进行连接编码(你只使用utf8///等latin1)ascii
  • 启用NO_BACKSLASH_ESCAPESSQL 模式

这三种情况任意一种你是100%安全的。
否则,即使您使用 PDO 准备语句,您也很可能受到攻击……

不得不提一下的是,mysql_real_escape_string只是DBMS里面MySQL的,PostgreSQL 里面会有pg_escape_string(),一般作者都会用DBMS自带的转义函数,如果不用自带的可以用比如说addslashes()。
addslashes绕过的方法在特定情况下其实也挺多,总结一下大概就是因为编码的原因导致绕过了要转义的字符,或者直接没有引号限制,列举一下:

  • 虽然使用了addslashes转义,但是缺没有加引号,直接无视过滤。
  • 使用了数据库字符gbk编码
  • 因为编码解码或者编码函数原因导致宽字节注入

所以,如果真的想要安全一些,最稳妥的方法就是请您避免 SQL 注入攻击的正确方法是将数据与 SQL 分离,以便数据保持数据,永远不会被SQL 解析器解释为命令

二、浅谈跨站脚本攻击

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android应用中实现防止DEX注入,可以采取以下措施: 1. 检测应用签名:在应用启动时,可以检查应用的签名是否与预期的签名一致。如果签名不匹配,可能意味着应用已被篡改。 ```java public static boolean isSignatureValid(Context context) { try { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); Signature[] signatures = packageInfo.signatures; // 验证签名与预期签名是否一致 // ... } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return false; } ``` 2. 检测应用运行环境:可以检查应用是否在预期的运行环境中执行。例如,可以检测当前应用是否在模拟器或Root设备上运行。 ```java public static boolean isEmulator() { return Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown") || Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for x86") || Build.MANUFACTURER.contains("Genymotion") || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || "google_sdk".equals(Build.PRODUCT); } public static boolean isRooted() { String[] paths = {"/system/bin/", "/system/xbin/", "/sbin/", "/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/xbin/", "/data/local/bin/", "/data/local/"}; for (String path : paths) { if (new File(path + "su").exists()) { return true; } } return false; } ``` 3. 内存完整性检测:可以定期检查应用的内存完整性,以防止DEX文件被恶意注入。可以使用一些第三方库或自行实现内存完整性检测的算法。 4. 加密DEX文件:可以使用加密算法对DEX文件进行加密,然后在运行时解密并加载。这样可以增加DEX文件的安全性,防止被恶意注入。 5. 应用签名校验:可以在应用启动时,对APK文件进行签名校验,确保APK文件没有被篡改。 这些措施并不是绝对的,但可以提高应用的安全性,防止DEX注入攻击。需要根据具体场景和需求选择合适的措施来保护应用的安全。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值