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

你有两个选择。

  1. 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=]

  1. 自定义 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..."
}