Search code examples
slack-api

Slack API forcefully overrides file extension with incorrect one


I'm using a Slack bot to upload a file via Slack API. File format is .csv, extension is .csv and I specify that filetype=csv. Yet, Slack API (file.upload) response tells me that Slack accepted my file as a Python file and forcefully appended a .py extension to it. Now every time anyone downloads that file, it's .csv file with a .py extension.

My guess is that it sees the """ and immediately thinks "oh, I know! It's a python-ish comment! it must be a Python file, regardless of what the requester says - I know better! I'll rename that file for him!"

Repro:

file (it was a valid csv, I've just trimmed its contents down)

/tmp/playground/slack_py_repro$ cat test_run_6588_errors_summary_by-action_report.csv
HTTP Status-Code=504 (Gateway Time-out) for ""{URL}"""
HTTP Status-Code=504 (Gateway Time-out) for ""{URL}"""
/tmp/playground/slack_py_repro$ curl -sLk -F file=@test_run_6588_errors_summary_by-action_report.csv -F "filename=test_run_6588_errors_summary_by-action_report.csv" -F "filetype=csv" -F "channels=${CHANNEL}" -H "Authorization: Bearer ${TOKEN}" https://slack.com/api/files.upload | jq
{
  "ok": true,
  "file": {
    "id": "<HIDDEN>",
    "created": 1655497834,
    "timestamp": 1655497834,
    "name": "test_run_6588_errors_summary_by-action_report.csv.py",
    "title": "test run 6588 errors summary by-action report.csv",
    "mimetype": "text/plain",
    "filetype": "python",
    "pretty_type": "Python",
    "editable": true,
    "size": 110,
    "mode": "snippet",
    "is_external": false,
    "external_type": "",
    "is_public": false,
/* ... */
  }
}

FWIW I think it also poses a security risk. I may upload a malicious Python file with a .csv extension, on the Slack web it'll say it's a .csv file, but when downloaded it'll become a .csv.py and an inattentive user will open it up expecting to see a spreadsheet. Of course, a Python runtime will kick in and it's a ggwp for that poor lad's computer/data/network.

What am I doing wrong? How do I tell the Slack API to keep its fingers away from my files' extensions?


Solution

  • I've reached out to Slack support. Turns out, that no matter what you do, Slack will try to auto-guess the uploaded file type itself. As the support rep put it, Slack must ensure that it can read and understand the file contents. When I addressed this justification as an alarming one (due to security reasons), I was explained that Slack needs to understand file contents in order to generate a preview for it (although it does not work for some files, e.g. for .xls the preview generation is explicitly disabled). The filetype hint does not do much. And in this particular case, Slack recognizes the """ as Python's multiline comment opening/closing sequence.

    As the support rep explained, this bug is not trivial to fix and might take some time. Why can't they reuse the same mechanism in the REST-api that's being successfully used in the web-api - I don't know. And, frankly, it's not my product to worry about such decisions.