hive SQL注入

0x01hive

hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。hive数据仓库工具能将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能将SQL语句转变成MapReduce任务来执行。

0x02背景

hive是个类sql语句,但不等同于SQL。见网上和公司没有关hive的正确使用方法和描述,导致hive注入的问题频出,所以对其进行安全防护的调研。

环境搭建

hive的搭建需要jdk1.8、mysql、hadoop、hive.如果使用javaSDK连接的话还需要启动hiveserver2

0x03HivePreparedStatement介绍

HivePreparedStatement是PreparedStatement的一个实现类,使用HivePreparedStatement数据库系统会对sql语句进行预编译处理,预处理语句将被预先编译好,这条预编译的sql查询语句能在将来的查询中重用,它比Statement对象生成的查询速度更快,并且可以防止SQL注入式攻击。

0x04使用对比

错误使用示例

1
2
3
4
5
6
7
8
9
10
11
public void selectData() {
String input_id = "1";
String sql = "select * from user_tb where id ="+input_id;
try (HiveStatement statement = connection.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
while (rs.next()) {
System.out.println("id="+rs.getInt("id")+ " name= "+rs.getString("name"));
}
} catch (SQLException e) {
logger.error("查询数据出错", e);
}
}

当用户将id1变为 1 or 1=1时,最终的会变为select * from user_tb where id = 1 or 1=1。导致返回了所有人的数据或者使用union查询(union查询也有很多限制,比如拼接的列字段类型必须一致否则就会报错。没有mysql那么宽泛可以拼接任何类型。且没有database()、user()一些内置的函数)其他表中的数据,效果如下

错误使用

正确效果示例:

使用HivePreparedStatement后,用户输入id变为 4’ or 1=‘1时,sql语句会对非法参数进行处理,使得黑客攻击失效,效果如下:
演示
演示

继承关系图

继承关系

0x05API、示例

具体使用可参考官方API、示例Demo:
http://hive.apache.org/javadocs/r2.1.1/api/org/apache/hive/jdbc/HivePreparedStatement.html

示例Demo:
使用方式和HiveStatement稍许有些不同,通过调用conn.preparedStatement(sql)方法可以获得HivePreparedStatement对象.通过SetXXX的形式传参。
示例1:

1
2
3
4
5
String path = "/tmp/data";
String sql = "load data local inpath ? overwrite into table user_tb";
HivePreparedStatement statement = (HivePreparedStatement) connection.prepareStatement(sql);
statement.setString(1, path);
statement.execute();

示例2:

1
2
3
4
5
6
7
String sql = "select * from user_tb where id =?";
HivePreparedStatement stmt = (HivePreparedStatement) connection.prepareStatement(sql);
stmt.setString(1,"2");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("name"));
}

示例3:

1
2
3
4
5
6
7
8
9
10
String sql = "update people set firstname=? , lastname=? where id=?";

HivePreparedStatement preparedStatement =
(HivePreparedStatement) connection.prepareStatement(sql);

preparedStatement.setString(1, "Gary");
preparedStatement.setString(2, "Larson");
preparedStatement.setLong (3, 123);

int rowsAffected = preparedStatement.executeUpdate();
文章作者: Screw
文章链接: http://screwsec.com/2020/01/11/hive-SQL%E6%B3%A8%E5%85%A5/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Screw's blog