How to get DOCX file from user and Save to my Uplink Server

I can use the file uploader component and .get_bytes() on the DOCX file, but I cannot find a way to write that messy DOCX byte string thing to a file on my uplink server.

Thoughts?

Hi Connor,

This should do it:

def save_some_media(media):
  with open("/tmp/my-uploaded-file.docx", "wb") as f:
    f.write(media.get_bytes())

(NB - do not allow the uploader to control the filename to which this file is written! (eg by using the .name property of a Media object.) That’s a recipe for allowing anyone on the internet to take over your computer.)

1 Like

How could anyone use just the name of the file to play with my system?

Ah. The vulnerability goes something like this:

# DO NOT USE THIS CODE. IT WILL ALLOW ANY USER TO TAKE OVER YOUR COMPUTER.
@anvil.server.callable
def do_not_use_this_function_ever_i_mean_it(media):
  with open('/tmp/uploads/' + media.name, 'wb') as f:
    f.write(media.get_bytes())

The .name property of a Media object (eg from a FileLoader) is supplied by the user, who may be malicious. If they upload a file with a name of "../../home/meredydd/important_file.txt" and pass it to this server function, this code will overwrite a file in my home directory! (Worse still, if they overwrite "../../home/meredydd/.ssh/authorized_keys" they can now log into my computer and do anything.)

Never, ever, allow untrusted user input to choose where you write files.

2 Likes

I am expecting a DOCX from the user. I call a script in the client that calls the uplink server script and that does exactly what you wrote here. What do I do?

BadZipFile: File is not a zip file
at C:/Python34/lib/zipfile.py, line 978
called from C:/Python34/lib/zipfile.py, line 937
called from C:/Python34/lib/site-packages/docx/opc/phys_pkg.py, line 101
called from C:/Python34/lib/site-packages/docx/opc/pkgreader.py, line 32
called from C:/Python34/lib/site-packages/docx/opc/package.py, line 116
called from C:/Python34/lib/site-packages/docx/api.py, line 25
called from C:/Users/USER/Desktop/UPLINKSCRIPT/UPLINKSCRIPT.py, line 34
called from Form1, line 34

I am still having a problem with DOCX files. Does anyone have a solution?

Hi Connor,

it works for me. Here’s what I did :

Form1 -
put a file upload component on it, and added this code :

from anvil import *
import anvil.server

class Form1(Form1Template):

  def __init__(self, **properties):
    # You must call self.init_components() before doing anything else in this function
    self.init_components(**properties)
    
    
  def file_loader_1_change (self, file, **event_args):
    # This method is called when a new file is loaded into this FileLoader
    anvil.server.call("dave",file)

On the target server I did this :

import anvil.server

@anvil.server.callable
def dave(media):
  with open("/tmp/my-uploaded-file.docx", "wb") as f:
      f.write(media.get_bytes())

anvil.server.connect("MY-KEY-HERE")
anvil.server.wait_forever()

The file uploaded fine.

Can you maybe share some code, I’l see if I can see any issues? Maybe share the docx file if it’s not too sensitive (PM if you like)?

2 Likes