[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/plz f2176dc56c 60/81: Change/Fix: Avoid command-line ar
From: |
ELPA Syncer |
Subject: |
[elpa] externals/plz f2176dc56c 60/81: Change/Fix: Avoid command-line arguments |
Date: |
Wed, 11 May 2022 17:58:02 -0400 (EDT) |
branch: externals/plz
commit f2176dc56c379b5d4676f5cd7c3511bd1399e53a
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>
Change/Fix: Avoid command-line arguments
---
notes.org | 8 +++++++-
plz.el | 50 ++++++++++++++++++++++++++++++--------------------
tests/test-plz.el | 43 ++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/notes.org b/notes.org
index 52f1f93164..b192071e2b 100644
--- a/notes.org
+++ b/notes.org
@@ -14,10 +14,16 @@
* Tasks
-** TODO Ensure that secrets are not leaked via command line or temp files
+** DONE Ensure that secrets are not leaked via command line or temp files
+CLOSED: [2021-08-15 Sun 15:34]
+:LOGBOOK:
+- State "DONE" from "TODO" [2021-08-15 Sun 15:34]
+:END:
e.g. =request.el= can leak secrets and other data via the command line and
[[https://github.com/tkf/emacs-request/blob/431d14343c61bc51a86c9a9e1acb6c26fe9a6298/request.el#L709][leftover
temp files]]. We want to handle this safely.
+[2021-08-15 Sun 15:33] Finally figured out how to do this using ~--config~.
It required some trial-and-error, since the curl man page doesn't explain how
to pass request bodies over STDIN after the arguments. But it works!
+
* Ideas
** TODO Use finalizers to clean up response buffers
diff --git a/plz.el b/plz.el
index 348f2f8b36..1a9fdd742f 100644
--- a/plz.el
+++ b/plz.el
@@ -184,7 +184,9 @@ the curl process buffer.")
"--compressed"
"--location"
"--dump-header" "-")
- "Default arguments to curl."
+ "Default arguments to curl.
+Note that these arguments are passed on the command line, which
+may be visible to other users on the local system."
:type '(repeat string))
(defcustom plz-connect-timeout 5
@@ -336,28 +338,35 @@ from a host, respectively.
NOQUERY is passed to `make-process', which see."
;; Inspired by and copied from `elfeed-curl-retrieve'.
-
;; NOTE: By default, for PUT requests and POST requests >1KB, curl sends an
;; "Expect:" header, which causes servers to send a "100 Continue" response,
which
;; we don't want to have to deal with, so we disable it by setting the
header to
;; the empty string. See <https://gms.tf/when-curl-sends-100-continue.html>.
;; TODO: Handle "100 Continue" responses and remove this workaround.
(push (cons "Expect" "") headers)
- (let* ((header-args (cl-loop for (key . value) in headers
- append (list "--header" (format "%s: %s" key
value))))
- (data-arg (pcase-exhaustive body-type
+ (let* ((data-arg (pcase-exhaustive body-type
('binary "--data-binary")
('text "--data")))
- (curl-args (append plz-curl-default-args header-args
- (when connect-timeout
- (list "--connect-timeout" (number-to-string
connect-timeout)))
- (when timeout
- (list "--max-time" (number-to-string timeout)))
- (pcase method
- ((or 'put 'post)
- (cl-assert body)
- (list data-arg "@-" "--request" (upcase
(symbol-name method)))))
- (list url)))
+ (curl-command-line-args (append plz-curl-default-args
+ (list "--config" "-")))
+ (curl-config-header-args (cl-loop for (key . value) in headers
+ collect (cons "--header" (format
"%s: %s" key value))))
+ (curl-config-args (append curl-config-header-args
+ (list (cons "--url" url))
+ (when connect-timeout
+ (list (cons "--connect-timeout"
+ (number-to-string
connect-timeout))))
+ (when timeout
+ (list (cons "--max-time"
(number-to-string timeout))))
+ (pcase method
+ ((or 'put 'post)
+ (cl-assert body)
+ (list (cons "--request" (upcase
(symbol-name method)))
+ ;; It appears that this must be
the last argument
+ ;; in order to pass data on the
rest of STDIN.
+ (cons data-arg "@-"))))))
+ (curl-config (cl-loop for (key . value) in curl-config-args
+ concat (format "%s \"%s\"\n" key value)))
(decode (pcase as
('binary nil)
(_ decode))))
@@ -369,7 +378,7 @@ NOQUERY is passed to `make-process', which see."
(process (make-process :name "plz-request-curl"
:buffer (current-buffer)
:coding 'binary
- :command (append (list plz-curl-program)
curl-args)
+ :command (append (list plz-curl-program)
curl-command-line-args)
:connection-type 'pipe
:sentinel #'plz--sentinel
:stderr (current-buffer)
@@ -398,13 +407,14 @@ NOQUERY is passed to `make-process', which see."
(setf plz-then then
plz-else else
plz-finally finally)
+ ;; Send --config arguments.
+ (process-send-string process curl-config)
(when body
(cl-typecase body
- (string (process-send-string process body)
- (process-send-eof process))
+ (string (process-send-string process body))
(buffer (with-current-buffer body
- (process-send-region process (point-min) (point-max))
- (process-send-eof process)))))
+ (process-send-region process (point-min) (point-max))))))
+ (process-send-eof process)
process))))
(cl-defun plz--curl-sync (_method url &key headers connect-timeout timeout
diff --git a/tests/test-plz.el b/tests/test-plz.el
index 37e8bad697..8fa933e6af 100644
--- a/tests/test-plz.el
+++ b/tests/test-plz.el
@@ -122,18 +122,21 @@
(ert-deftest plz-post-jpeg-string nil
(let* ((jpeg-to-upload (plz-get-sync "https://httpbin.org/image/jpeg"
:as 'binary))
+ (response-json)
(response-jpeg)
(process (plz 'post "https://httpbin.org/post"
:headers '(("Content-Type" . "image/jpeg"))
:body jpeg-to-upload :body-type 'binary
:as #'json-read
:then (lambda (json)
- (setf response-jpeg
+ (setf response-json json
+ response-jpeg
(base64-decode-string
(string-remove-prefix
"data:application/octet-stream;base64,"
(alist-get 'data
json))))))))
(should (equal 'jpeg (image-type-from-data jpeg-to-upload)))
(plz-test-wait process)
+ (should response-json)
(should (equal 'jpeg (image-type-from-data response-jpeg)))
(should (equal (length jpeg-to-upload) (length response-jpeg)))
(should (equal jpeg-to-upload response-jpeg))))
@@ -177,6 +180,44 @@
(should-error (plz-get-sync "https://httpbin.org/get"
:as 'buffer)))
+;;;;; Headers
+
+;; These tests were added when plz--curl was changed to send headers
+;; with "--config" rather than on the command line.
+
+(ert-deftest plz-get-with-headers ()
+ (let* ((response-json)
+ (process (plz 'get "https://httpbin.org/get"
+ :headers '(("X-Plz-Test-Header" . "plz-test-header-value"))
+ :as #'json-read
+ :then (lambda (json)
+ (setf response-json json)))))
+ (plz-test-wait process)
+ (let-alist response-json
+ (should (equal "plz-test-header-value" .headers.X-Plz-Test-Header)))))
+
+(ert-deftest plz-post-with-headers ()
+ (let* ((alist (list (cons "key" "value")))
+ (response-json)
+ (process (plz 'post "https://httpbin.org/post"
+ :headers '(("Content-Type" . "application/json")
+ ("X-Plz-Test-Header" . "plz-test-header-value"))
+ :body (json-encode alist)
+ :as #'json-read
+ :then (lambda (json)
+ (setf response-json json)))))
+ (plz-test-wait process)
+ (let-alist response-json
+ (should (equal "plz-test-header-value" .headers.X-Plz-Test-Header))
+ (should (equal "value" (alist-get 'key (json-read-from-string
.data)))))))
+
+(ert-deftest plz-get-json-with-headers-sync ()
+ (let-alist (plz-get-sync "https://httpbin.org/get"
+ :headers '(("X-Plz-Test-Header" . "plz-test-header-value"))
+ :as #'json-read)
+ (should (string-match "curl" .headers.User-Agent))
+ (should (equal "plz-test-header-value" .headers.X-Plz-Test-Header))))
+
;;;;; Errors
(ert-deftest plz-get-curl-error nil
- [elpa] externals/plz 7eff40f276 44/81: Add: plz-finally, (continued)
- [elpa] externals/plz 7eff40f276 44/81: Add: plz-finally, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 27010c20e1 45/81: Meta: Update makem.sh, etc., ELPA Syncer, 2022/05/11
- [elpa] externals/plz f34efa052c 48/81: Fix: set-buffer-multibyte nil for binary, ELPA Syncer, 2022/05/11
- [elpa] externals/plz e977a046a3 50/81: Change: (plz-http-response-status-line-regexp) Match at BOL, ELPA Syncer, 2022/05/11
- [elpa] externals/plz f12f907719 52/81: Change/Fix: (plz--curl) Disable Expect header, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 701e79c3e8 55/81: Tidy: Remove obsolete functions, ELPA Syncer, 2022/05/11
- [elpa] externals/plz b412258c9d 56/81: Add: :timeout argument (curl's --max-time), ELPA Syncer, 2022/05/11
- [elpa] externals/plz 87007fc612 57/81: Add: FIXMEs, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 709a14740f 58/81: Tidy: Docstrings, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 93a2ccaaa8 59/81: Fix: Run curl in temporary-file-directory, ELPA Syncer, 2022/05/11
- [elpa] externals/plz f2176dc56c 60/81: Change/Fix: Avoid command-line arguments,
ELPA Syncer <=
- [elpa] externals/plz ac5bc006f3 62/81: Docs: Add readme, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 278391562a 69/81: Docs: Tidy, ELPA Syncer, 2022/05/11
- [elpa] externals/plz a5ccf48d80 70/81: Tests: Add check/error to a test, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 2f48423834 72/81: Docs: Add mascot, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 0b32c64f77 74/81: Notes: Rename file, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 7e456638a6 75/81: Meta: Move notes to orphan branch, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 69d5bf74f6 77/81: Fix: (plz--coding-system) Alist key, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 1d3efc036c 78/81: Add: (plz) DELETE method, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 9e308f1833 80/81: Meta: Tidy headers, etc. for ELPA, ELPA Syncer, 2022/05/11
- [elpa] externals/plz 9156de9c59 81/81: Release: 0.1, ELPA Syncer, 2022/05/11