pythonjsonpython-requestssafe-browsing

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?


Solution

  • 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())