0

I have a script that tries to update the Google DDNS record with my public IP using the Google's API as described here. The idea is to replicate this HTML query:

Example HTTP query:
POST /nic/update?hostname=subdomain.yourdomain.com&myip=1.2.3.4 HTTP/1.1
Host: domains.google.com
Authorization: Basic base64-encoded-auth-string User-Agent: Chrome/41.0 your_email@yourdomain.com

The full API url is https://domains.google.com/nic/update. Here is my python script

def pub_ip(url='https://domains.google.com/checkip'):
  r = get(url)
  if not r.ok:
    raise Exception('GET failed with code {}'.format(r.status_code))
  return r.text

def change_ddns_ip(ip):
  print('Setting new DDNS IP to {}'.format(ip))
  AUTH = 'Basic {}'.format(str(b64encode(b'user:pass'))[2:-1])
  HOSTNAME = 'sub.domain.com'
  POST_URL = 'https://domains.google.com/nic/update?hostname={}&myip={}'.format(HOSTNAME, ip)
  headers = {
    'User-Agent': 'DDNS Update Python Script',
    'From': 'email@dm.com',
    'Host': 'domains.google.com',
    "Authorization": AUTH
  }
  r = post(POST_URL, headers=headers)
  if not r.ok:
    raise Exception('POST failed with code {}'.format(r.status_code))
  return r.text

def process_text(text):
  status, ip = text.split(' ')
  print(status)
  if status != 'good':
    raise Exception(text)
  return ip

ip = pub_ip()
text = change_ddns_ip(ip)
_ip = process_text(text)

while True:
  ip = pub_ip()
  if _ip != ip:
    text = change_ddns_ip(ip)
    _ip = process_text(text)
  sleep(5)

My main concern is the POST request done in change_ddns_ip(ip). Did I make it securely? The url in it looks like url?param=val which makes me nervous because I thought POST did not send data in the url? Could someone clarify why does then the url above look like it does?

Since there is sensitive information being sent here, I'll really appreciate if someone took a look and told me if there are any security flaws anywhere in the script? It is meant to run as a daemon. Here are the import statements that I omitted from above.

from requests import get, post
from base64 import b64encode
from time import sleep
scribe
  • 673
  • 2
  • 6
  • 17
  • Are you using HTTPS and are you validating certificates (the default requests behavior)? Then you're fine. Whether the data is in the query string or the body doesnt matter at all from a security perspective. – Jonathon Reinhart Jan 12 '21 at 02:50
  • I think I am using HTTPS because the request url starts with `https://` and no idea about the certificates. That is why I posted the code. Could you take a look? – scribe Jan 12 '21 at 02:57

1 Answers1

0

Yes, when using HTTPS the domain may be in plaintext but the rest of the URL is going to be encrypted. See this answer for technical details: https://stackoverflow.com/a/38727920

Also note that HTTP methods do not have anything to do with URLs. POST requests can have query parameters and headers which are able to be used as well as the request body.

im_baby
  • 912
  • 1
  • 8
  • 14
  • Well, yeah but my concern was that if someone is logging the urls then it takes more time to get to the request body haha.. So is my request overall secure? – scribe Jan 12 '21 at 03:04
  • 1
    Did you read the link? They show wire captures where you can not see the URL when it is a HTTPS request. – im_baby Jan 12 '21 at 03:09