Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将具有修改的字段名和白名单验证的SQL语句传递给RPC函数。它是安全的并且是一种常见的做法吗?_Sql_Json_Rpc_Json Rpc - Fatal编程技术网

将具有修改的字段名和白名单验证的SQL语句传递给RPC函数。它是安全的并且是一种常见的做法吗?

将具有修改的字段名和白名单验证的SQL语句传递给RPC函数。它是安全的并且是一种常见的做法吗?,sql,json,rpc,json-rpc,Sql,Json,Rpc,Json Rpc,我创建了一个API,其中可以使用JSON-RPC将SQL语句作为参数传递。API提供了一个表和列名字典,因此客户机不知道实际的数据库表和列名,可以使用GET方法进行访问。可以使用POST方法访问实际的API功能 我使用令牌和正则表达式验证只允许带有有效令牌的请求,只允许某些字符来阻止SQL注入,并阻止使用“drop、insert、into、update”。只有“select”语句是可能的,但在需要时,指定用户可以使用其他语句 我的问题是,这是过程调用的安全方法吗?如果是,这是否一种普遍做法?我试

我创建了一个API,其中可以使用JSON-RPC将SQL语句作为参数传递。API提供了一个表和列名字典,因此客户机不知道实际的数据库表和列名,可以使用GET方法进行访问。可以使用POST方法访问实际的API功能

我使用令牌和正则表达式验证只允许带有有效令牌的请求,只允许某些字符来阻止SQL注入,并阻止使用“drop、insert、into、update”。只有“select”语句是可能的,但在需要时,指定用户可以使用其他语句

我的问题是,这是过程调用的安全方法吗?如果是,这是否一种普遍做法?我试着使用浏览器和邮递员访问API,它似乎可以工作。不过,我主要关心的是安全问题

下面是一个邮递员JSON-RPC请求正文示例

{"jsonrpc": "2.0", "method": "rpc_ql", "params": {"token" : "12345", "query" : "select person_id, person_name, person_gender from persons where person_id = 123"}, "id": 1}
/**
*RPC-QL-RPC-QL是一种基于SQL的查询语言,可访问
*-通过远程过程调用(RPC)API。
*
*@package RPC-QL(JSON-RPC上的SQL)
*@作者Raymund John Ang
*@license-MIT-license
*/
//使用JSON-RPC 2.0规范处理发布的JSON数据
$data=json\u解码(文件\u获取\u内容('php://input",对),;
$jsonrpc=$data['jsonrpc'];
$method=$data['method'];
$params=$data['params'];
$id=$data['id'];
//远程API函数
函数rpc_ql()
{
全球$jsonrpc;
全球美元法;
全球$params;
全球$id;
//表和列字段字典
$dictionary=[['Table'=>'persons',
'Fields'=>['person\u id'=>'整数-个人id号',
'人名'=>'字符串-人名',
“person_gender”=>“字符串-男性或女性”,
“个人出生日期”=>“字符串-格式YYYY-MM-DD']],
['Table'=>'places',
'Fields'=>['place\u id'=>'整数-该位置的id号',
“地点名称”=>“字符串-地点名称”,
'place_state'=>'字符串-位置所在的状态']];
//使用GET请求显示字典。
if($服务器['REQUEST\u METHOD']='GET')echo json\u encode($dictionary);
//通过POST请求访问API功能。
如果($\u服务器['REQUEST\u METHOD']=='POST'){
//需要基于JSON-RPC 2.0和SQL的参数
如果(empty($jsonrpc)| | empty($method)| | empty($params['token'])| | | empty($id))退出('请设置“jsonrpc”、“method”、“token”和“query”参数,并请求“id”);
$token=$params['token'];
$query=$params['query'];
//令牌验证-令牌应为12345
如果(!hash_等于(hash('sha256',12345),hash('sha256',$token)))退出('token身份验证失败');
//查询验证-查询应该是字母数字的,带有几个可接受的字符和列入黑名单的SQL命令。
if(preg_match('/^[a-zA-Z0-9,*=()\']+$/i',$query)和&!preg_match('/(drop | insert | into | update)/i',$query)){
//表和列字段转换器
$mod_query=str_replace('persons','db_persons',$query);//persons表;$query的初始转换。
$mod_query=str_replace('person_id','db_person_id',$mod_query);//后续转换$mod_query。
$mod_query=str_replace('person_name','db_person_name',$mod_query);
$mod_query=str_replace('person_gender','db_person_gender',$mod_query);
$mod_query=str_replace('person_birth_date','db_person_birth date',$mod_query);
$mod_query=str_replace('places','db_places',$mod_query);//places表
$mod_query=str_replace('place_id','db_place_id',$mod_query);
$mod_query=str_replace('place_name','db_place_name',$mod_query);
$mod_query=str_replace('place_state','db_place_state',$mod_query);
//如果$mod_查询包含查询,请将$error设置为null。
如果($mod_query!==false)$error=null;
$response=['jsonrpc'=>$jsonrpc,'result'=>$mod_query,'error'=>$error,'id'=>$id];
echo json_编码($response);
}否则{
//验证失败
$error_message=“该查询无效。它应仅包含字母数字字符、空格、'.'、'.'、'*'、'='、'('.')'和''.''。只允许使用SELECT语句。”;
$response=['jsonrpc'=>$jsonrpc',result'=>null,'error'=>32600,'message'=>$error\u message],'id'=>$id];
echo json_编码($response);
}
}
}
//如果函数存在,则执行方法
如果(函数_存在($method)){
返回$method();
}否则{
$error_message='抱歉,包含的方法不存在';
$response=['jsonrpc'=>$jsonrpc,'result'=>null,'error'=>32602,'message'=>$error\u message],'id'=>$id];
echo json_编码($response);
}
简而言之:没有

即使您尽可能使其安全,这种方法仍然存在安全风险。关于当前代码将如何中断的一个非常简单的示例:

truncate table persons
这将有效地删除表
db\u persons
中的所有记录

只要您允许客户机的任何输入直接包含在数据库查询中,您的系统迟早会崩溃。

简言之:否

即使您尽可能使其安全,这种方法仍然存在安全风险。关于当前代码将如何中断的一个非常简单的示例:

truncate table persons
这将有效地删除表
db\u persons
中的所有记录


只要您允许客户机的任何输入直接包含在数据库查询中,您的系统迟早会崩溃。

我不会这么说。除非你加密你的流量,否则任何截获你的JSON的人都会泄露你所有的DB表和模式,这只是一个信息泄露。如果你使用它