Swedish Mike Swedish Mike - 1 month ago 18
JSON Question

Unexpected response with Google Safe Browsing API v4 and Python requests

I'm trying to implement a small function to verify possible phishing URL's and thought that using Google Safe Browsing API would be a good start.

After reading the API documentation I thought I had a handle on things and cobbled together the following code:

import requests
import json

url = "https://safebrowsing.googleapis.com/v4/threatMatches:find?key=<REDACTED>"
headers = {'content-type': 'application/json'}

payload = {'client': {'clientId': "mycompany", 'clientVersion': "0.1"},
'threatInfo': {'threatTypes': ["SOCIAL_ENGINEERING", "MALWARE"],
'platformTypes': ["ANY_PLATFORM"],
'threatEntryTypes': ["URL"],
'threatEntries:': [{'url': "http://www.urltocheck1.org"}]}}

print (json.dumps(payload, indent=4))

r = requests.post(url, headers=headers, json=payload)


If I do a


print (json.dumps(payload, indent=4)


it all looks ok. However, the reply I get back from Google doesn't agree.


{'error': {'message': 'Invalid JSON payload received. Unknown name
"threat_entries:" at \'threat_info\': Cannot find field.', 'status':
'INVALID_ARGUMENT', 'code': 400, 'details': [{'@type':
'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations':
[{'field': 'threat_info', 'description': 'Invalid JSON payload
received. Unknown name "threat_entries:" at \'threat_info\': Cannot
find field.'}]}]}} {'X-Frame-Options': 'SAMEORIGIN',
'Transfer-Encoding': 'chunked', 'Cache-Control': 'private', 'Date':
'Tue, 25 Oct 2016 07:55:30 GMT', 'Content-Type': 'application/json;
charset=UTF-8', 'Alt-Svc': 'quic=":443"; ma=2592000;
v="36,35,34,33,32"', 'X-Content-Type-Options': 'nosniff',
'Content-Encoding': 'gzip', 'X-XSS-Protection': '1; mode=block',
'Server': 'ESF'} application/json; charset=UTF-8


I can't - as usual - spot my mistake. Can someone else spot it and possibly put me on the correct track?

Answer

Just remove unnecessary colon after threatEntries and it should work just fine.

Also if you are using requests version 2.4.2 or newer you do not need to insert content-type header to your code, instead you could move your key to the params section:

import requests
import json

api_key='your_key'
url = "https://safebrowsing.googleapis.com/v4/threatMatches:find"
payload = {'client': {'clientId': "mycompany", 'clientVersion': "0.1"},
        'threatInfo': {'threatTypes': ["SOCIAL_ENGINEERING", "MALWARE"],
                       'platformTypes': ["ANY_PLATFORM"],
                       'threatEntryTypes': ["URL"],
                       'threatEntries': [{'url': "http://www.urltocheck1.org"}]}}
params = {'key': api_key}
r = requests.post(url, params=params, json=payload)
# Print response
print(r) 
print(r.json())