Salesforce REST API 如何避免泄露查询参数中的敏感数据
Salesforce REST API how to avoid leaking sensitive data in query parameter
我正在尝试使用 REST API 和 运行 查询以下问题:
在查询端点上使用 GET 请求会暴露整个查询字符串,其中可能包含 SSN、phone 号码等敏感数据...
https://[instance-url].my.salesforce.com/services/data/v48.0/query/?q=SELECT Id FROM Contact WHERE SSN__c = '123456789'
如何使用 rest api 安全地进行此类查询?
是否有一个等效的请求,我可以使用至少 POST 请求和 post 正文作为查询?因为那部分是通过 https 加密的。
感谢您的帮助
据我所知,salesforce 仅提供 GET 方法来执行 SOQL 查询。人们可以在他们的组织中编写他们自己的 REST 端点,接受 body 中的查询并执行它,但我认为那是浪费时间。
查询字符串参数在 https
上受到保护。这是一个常见的误解,人们认为整个 url 在传输中以纯文本形式打开。当向 https
url 发出请求时,它首先会建立到 [instance-url].my.salesforce.com
的安全隧道,然后通过安全隧道传输 url 的其余部分和任何其他数据。
如果您担心中间人攻击会从您的查询字符串中嗅出 SSN,请不要担心。一个缺点是,如果您是从浏览器而不是编程调用访问此 url,那么浏览器有机会 stored/cache 以获取历史记录或自动完成,那么它就不会那么好.
但我怀疑您是否能够通过浏览器执行此操作,因为 salesforce 需要在授权 header 中设置不记名令牌,而且据我所知没有简单的方法可以设置 header在浏览器中键入 url 或单击 link。
要了解有关查询字符串如何通过 https 确保安全的更多信息,请参阅 this Whosebug question
你有两个选择。
- Parameterized Search API。此选项开箱即用,使用 POST 作为方法。 API 是 Salesforce 基于文本的搜索引擎的 RESTful 界面。通常,基于文本的搜索使用 SOSL 作为查询语言。参数化搜索 API 跳过 SOSL 并为您提供更容易使用的选项。
如果你POST下面的正文/services/data/v48.0/parameterizedSearch
{
"q": "123456789",
"sobjects": [
{
"name": "Contact",
"where": "SSN__c = '123456789'"
}
],
"fields": ["id"]
}
你应该看到类似这样的响应,假设单个记录是 return 通过搜索编辑的(ID 已编辑):
{
"searchRecords" : [ {
"attributes" : {
"type" : "Contact",
"url" : "/services/data/v48.0/sobjects/Contact/003..."
},
"Id" : "003..."
} ]
}
JSON 有效负载中 q
键的值必须与 where
key/clause 中的值相同。您正在搜索索引中的所有对象和所有字段中对 123456789
进行全文搜索。这可能 return 条记录..但是您正在以结构化的方式过滤搜索以保证您只会看到 Contact
条记录,其中 SSN__c = '123456789'
。只要您尝试检索的对象 + 字段存在于索引中,您在这个特定示例中通过参数化搜索看到的结果将与通过 /query
[ 的 SOQL 查询的结果相同=25=]
- 自定义 REST API(又名 Apex REST / Apex 网络服务)。对于像您这样的案例,这是典型的实施选项。您可以通过 POST 发送任何有效载荷,然后根据需要对其进行处理。
顶点class:
@RestResource(urlMapping='/findcontactbyssn')
global class ContactResource {
@HttpPost
global static void findContactBySSN() {
SearchRequest input = (SearchRequest)JSON.deserialize(RestContext.request.requestBody.toString(),SearchRequest.class);
Contact c = [SELECT Id FROM Contact WHERE SSN__c = :input.ssn];
SearchResponse output = new SearchResponse();
output.id = c.id;
RestContext.response.responseBody = Blob.valueOf(JSON.serialize(output));
RestContext.response.statusCode = 200;
}
class SearchRequest {
public String ssn {get;set;}
}
class SearchResponse {
public String id {get;set;}
}
}
POST 到 /services/apexrest/findcontactbyssn
和
{
"ssn": "12345678"
}
你应该会看到这个回复:
{
"id": "003..."
}
我正在尝试使用 REST API 和 运行 查询以下问题:
在查询端点上使用 GET 请求会暴露整个查询字符串,其中可能包含 SSN、phone 号码等敏感数据...
https://[instance-url].my.salesforce.com/services/data/v48.0/query/?q=SELECT Id FROM Contact WHERE SSN__c = '123456789'
如何使用 rest api 安全地进行此类查询? 是否有一个等效的请求,我可以使用至少 POST 请求和 post 正文作为查询?因为那部分是通过 https 加密的。
感谢您的帮助
据我所知,salesforce 仅提供 GET 方法来执行 SOQL 查询。人们可以在他们的组织中编写他们自己的 REST 端点,接受 body 中的查询并执行它,但我认为那是浪费时间。
查询字符串参数在 https
上受到保护。这是一个常见的误解,人们认为整个 url 在传输中以纯文本形式打开。当向 https
url 发出请求时,它首先会建立到 [instance-url].my.salesforce.com
的安全隧道,然后通过安全隧道传输 url 的其余部分和任何其他数据。
如果您担心中间人攻击会从您的查询字符串中嗅出 SSN,请不要担心。一个缺点是,如果您是从浏览器而不是编程调用访问此 url,那么浏览器有机会 stored/cache 以获取历史记录或自动完成,那么它就不会那么好.
但我怀疑您是否能够通过浏览器执行此操作,因为 salesforce 需要在授权 header 中设置不记名令牌,而且据我所知没有简单的方法可以设置 header在浏览器中键入 url 或单击 link。
要了解有关查询字符串如何通过 https 确保安全的更多信息,请参阅 this Whosebug question
你有两个选择。
- Parameterized Search API。此选项开箱即用,使用 POST 作为方法。 API 是 Salesforce 基于文本的搜索引擎的 RESTful 界面。通常,基于文本的搜索使用 SOSL 作为查询语言。参数化搜索 API 跳过 SOSL 并为您提供更容易使用的选项。
如果你POST下面的正文/services/data/v48.0/parameterizedSearch
{
"q": "123456789",
"sobjects": [
{
"name": "Contact",
"where": "SSN__c = '123456789'"
}
],
"fields": ["id"]
}
你应该看到类似这样的响应,假设单个记录是 return 通过搜索编辑的(ID 已编辑):
{
"searchRecords" : [ {
"attributes" : {
"type" : "Contact",
"url" : "/services/data/v48.0/sobjects/Contact/003..."
},
"Id" : "003..."
} ]
}
JSON 有效负载中 q
键的值必须与 where
key/clause 中的值相同。您正在搜索索引中的所有对象和所有字段中对 123456789
进行全文搜索。这可能 return 条记录..但是您正在以结构化的方式过滤搜索以保证您只会看到 Contact
条记录,其中 SSN__c = '123456789'
。只要您尝试检索的对象 + 字段存在于索引中,您在这个特定示例中通过参数化搜索看到的结果将与通过 /query
[ 的 SOQL 查询的结果相同=25=]
- 自定义 REST API(又名 Apex REST / Apex 网络服务)。对于像您这样的案例,这是典型的实施选项。您可以通过 POST 发送任何有效载荷,然后根据需要对其进行处理。
顶点class:
@RestResource(urlMapping='/findcontactbyssn')
global class ContactResource {
@HttpPost
global static void findContactBySSN() {
SearchRequest input = (SearchRequest)JSON.deserialize(RestContext.request.requestBody.toString(),SearchRequest.class);
Contact c = [SELECT Id FROM Contact WHERE SSN__c = :input.ssn];
SearchResponse output = new SearchResponse();
output.id = c.id;
RestContext.response.responseBody = Blob.valueOf(JSON.serialize(output));
RestContext.response.statusCode = 200;
}
class SearchRequest {
public String ssn {get;set;}
}
class SearchResponse {
public String id {get;set;}
}
}
POST 到 /services/apexrest/findcontactbyssn
和
{
"ssn": "12345678"
}
你应该会看到这个回复:
{
"id": "003..."
}