사용자 이름과 비밀번호로 cURL을 사용하십니까?


466

사용자 이름 / 암호가 필요한 URL에 액세스하고 싶습니다. 컬로 액세스하려고합니다. 지금 나는 다음과 같은 일을하고있다 :

curl http://api.somesite.com/test/blah?something=123

오류가 발생합니다. 위의 명령과 함께 사용자 이름과 비밀번호를 지정해야한다고 생각합니다.

어떻게해야합니까?

답변:


693

-u플래그를 사용하여 사용자 이름을 포함하면 curl에서 암호를 묻습니다.

curl -u username http://example.com

명령에 암호를 포함시킬 수도 있지만 bash 기록에 암호가 표시됩니다.

curl -u username:password http://example.com

109
콘솔에서이 작업을 수행하면 암호가 잘못된 기록으로 유지됩니다. -u user 만 지정하면 CURL이 에코 없음 모드에서 비밀번호를 묻습니다.
Cristian Vrabie

25
@CristianVrabie 기술적으로 정확하지만 프롬프트를 허용하지 않는 자동화 된 스크립트에서 실행하는 경우 올바르지 않습니다. 그 문제에 대한 해결책이 궁금합니다.
Ligemer

26
@OmarOthman 스크립트에서 curl을 실행하면 자격 증명이 분명히 기록에 남지 않지만 ps (1)에 표시됩니다. 수정 :print -- '-u username:password' > somewhere && curl -K somewhere http://...
단지 누군가가

7
@Jay 환경 변수는 명령 실행 전에 평가됩니다. 비밀번호는 여전히 ps 출력에 표시됩니다.
Robert Važan

8
요점을 설명하지는 않지만 내 대답 ( stackoverflow.com/a/27894407/758174, 즉 사용 --netrc-file)이 더 안전 하다고 생각 합니다. 암호를 기록, ps, 스크립트 등에서 제외시킵니다. 이는 모든 스크립트 및 인증 된 모든 용도에 사용하는 유일한 형식입니다 curl.
Pierre D

253

하는 것이 더 안전합니다 :

curl --netrc-file my-password-file http://example.com

... 명령 줄에 일반 사용자 / 암호 문자열을 전달하는 것은 좋지 않습니다.

비밀번호 파일의 형식은 다음과 man curl같습니다.

machine <example.com> login <username> password <password>

노트 :

  1. 기계 이름은 포함 하거나 유사 해서는 안됩니다https:// ! 호스트 이름 만
  2. ' machine', ' login'및 ' password' 단어 는 키워드 일뿐입니다. 실제 정보는 키워드 뒤에 나오는 것입니다.

10
예, 암호는 프로세스 목록 및 명령 기록에서 제외됩니다. 이 작업을 수행하는 가장 바람직한 방법, 그리고 조금만 더 작업 :)
AC Capehart

8
이것은 분명히 받아 들여지는 대답이어야합니다. 명령 줄의 암호는 끔찍한 관행입니다. (이것은 널리 알려진 사실입니다.)
ELLIOTTCABLE

6
또한 플래그를 사용할 수 -K <file>또는 --config <file>파일 또는 표준 입력을 통해 컬 플래그를받을 수 있습니다. (경고 :와 혼동하지 -k--insecure!)
Rufflewind

2
이 curl 방법은 자격 증명을 기록 및 프로세스 상태에서 유지하지만 내 암호 파일에 사용자 이름과 암호를 일반 텍스트로 남겨두면 기록 파일에 정보를 두는 것보다 더 나쁜 공격 경로를 만듭니다. 예를 들어 bash는 권한을 자동으로 제한합니다 히스토리 파일 사용자 이름 / 암호를 설정하는 스크립트와 같은 환경 변수를 사용하는 경우에도 비슷한 문제가 발생합니다. 스크립트가 안전하지 않으면 자격 증명도 마찬가지입니다.
스티븐은 쉽게 즐겁게

5
나는 동의하지 @SteventheEasilyAmused, 그것은 일반 텍스트를 사용하는 것이 훨씬 낫다 .netrc그렇게 만 적절하게 엄격한 권한이있는 파일을 사용자의 사용자 수 있도록 다른 메커니즘 (예를 들어 명령 행 인수)보다, 그것을 읽을 수있는 다른 사용자가 정보를 읽으십시오.
Ken Williams

76

또는 같은 것이지만 다른 구문

curl http://username:password@api.somesite.com/test/blah?something=123

1
더 많은 상황에서 사용할 수 있기 때문에 그 구문을 사용합니다. cURL이없고 wGet이없는 Windows cmd와 마찬가지로를 사용 start "" "http://username:password@api.somesite.com/test/blah?something=123"합니다. 어디서나 시작할 수 있습니다. D; 또한 로그인을 ftp를 적용
m3nda

8
재미있는 문자를 사용하려면 사용자 이름과 비밀번호를 URL로 인코딩해야합니다.
diachedelic

2
대부분의 사람들은 스니핑하기 쉽기 때문에이 예제와 같이 URL에 비밀번호 (또는 사용자 이름)를 보내지 않는 것을 알고 있습니다. 그것으로 말했다; 나는 그것을 권장하지 않지만 당신이하는 일을 알고있을 때만 사용하십시오.
LosManos

1
이것은 고풍스럽고 사용 해서는 안됩니다 . 이것은 FTP 일입니다 : o
Qix-MONICA WASREATED

2
불행히도, 이것은 프로세스 목록에 암호를 보이게합니다.
Mark Ribau

63

다음과 같이 작성하여 사용자 이름을 보낼 수도 있습니다.

curl -u USERNAME http://server.example

그러면 Curl에서 암호를 묻고 화면에 암호가 표시되지 않습니다 (또는 명령을 복사 / 붙여 넣기해야하는 경우).


27

스크립트에서 암호를 안전하게 전달하려면 (즉, ps auxf 또는 로그와 함께 표시되지 않도록) -K- 플래그 (stdin에서 구성 읽기)와 heredoc을 사용하여 암호를 수행 할 수 있습니다.

curl --url url -K- <<< "--user user:password"

2
--config옵션 (-K)을 참조 해 주셔서 감사합니다 . 아마도 더 나은 해결책은 "--user user : password"를 파일에 넣는 것입니다. -K the file그러면 모든 스크립트에 하나의 비밀번호 사본 만있게됩니다. . 단일 파일을 보호하는 것이 훨씬 쉽습니다.
Chris Cogdon

1
비밀번호 만 파일에있는 유사한 옵션 : cat "${password_filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-. -K-오래된 macOS bash 인 YMMV의 URL 앞에 넣어야했습니다 .
마크 리 바우

12

일반적으로 CURL 명령은

curl https://example.com\?param\=ParamValue -u USERNAME:PASSWORD

비밀번호가 없거나 비밀번호를 요구하는 명령 프롬프트를 건너 뛰려면 비밀번호 섹션을 비워 두십시오.

curl https://example.com\?param\=ParamValue -u USERNAME:


1
참고 : 비밀번호는 셸 기록 및 프로세스 목록에 표시됩니다.
Mark Ribau

10
curl -X GET -u username:password  {{ http://www.example.com/filename.txt }} -O

1
참고 : 비밀번호는 셸 기록 및 프로세스 목록에 표시됩니다.
Mark Ribau

8

암호가 최소한으로 나타나지 않도록하려면 .bash_history:

curl -u user:$(cat .password-file) http://example-domain.tld

6
이 경우 암호는 여전히 프로세스 목록에있게됩니다. 예를 들어 누군가 ps auxw |grep curl가 적시에 볼 수 있습니다 . 마찬가지로 다음을 통해 비밀번호를 실행할 경우sudo
Adam Katz

1
이 방법을 사용하면 암호가 파일 (.password-file)에 존재하며 .bash 기록보다 안전하지 않을 수 있습니다. 이것에 대한 좋은 부분은 암호입니다. URL과 사용자 이름은 .password-file에서 유출되지 않습니다.
스티븐은 쉽게 즐겁게


6

다른 답변에 따르면 netrc는 내가 읽은 내용에 따라 사용자 이름과 비밀번호를 지정하도록 제안했습니다. 구문 세부 사항은 다음과 같습니다.

https://ec.haxx.se/usingcurl-netrc.html

다른 답변과 마찬가지로이 질문과 관련하여 보안에주의를 기울여야한다는 점을 강조하고 싶습니다.

나는 전문가는 아니지만 다음과 같은 통찰력을 얻었습니다.

https://ec.haxx.se/cmdline-passwords.html

요약:

은 Using 프로토콜의 암호화 된 버전 (HTTPS HTTP 대) (FTP 대 FTPS)를 피하기 네트워크 누설을 도울 수 있습니다.

netrc 를 사용하면 명령 줄 누출을 피할 수 있습니다.

한 단계 더 나아가려면 gpg를 사용하여 netrc 파일을 암호화 할 수도 있습니다

https://brandur.org/fragments/gpg-curl

이를 통해 자격 증명이 일반 텍스트로 "휴면"(저장)되지 않습니다.


5

가장 쉽고 안전한 방법은 환경 변수를 사용하여 자격 증명을 저장 / 검색하는 것입니다. 따라서 curl 명령은 다음과 같습니다.

curl -Lk -XGET -u "${API_USER}:${API_HASH}" -b cookies.txt -c cookies.txt -- "http://api.somesite.com/test/blah?something=123"

그런 다음 편안한 API를 호출 WWW_Authentication하고 Base64로 인코딩 된 값으로 API_USER및 http 헤더를 http 헤더에 전달하십시오 API_HASH. (가) -Lk단지 HTTP 30 배 리디렉션을 따르지 및 취급 안전하지 않은 TLS를 사용하도록 컬을 알려줍니다 (즉 SSL 오류를 무시). 이중 --은 명령 줄 플래그 처리를 중지하기 위해 bash 구문 설탕입니다. 또한 -b cookies.txt-c cookies.txt플래그는 쿠키를 -b보내고 -c로컬에 쿠키를 저장 하여 쿠키를 처리합니다 .

매뉴얼에는 인증 방법에 대한 더 많은 예가 있습니다.


1
"-Lk"를 사용하면 MITM (man-in-the-middle) 공격에 노출 될 수 있으므로 해당 옵션에주의하십시오.
GuyPaddock

4
bash는 변수를 확장하므로 프로세스 목록에 확장이 나타납니다.
Chris Cogdon


4

자격 증명을 curl에 전달하는 가장 안전한 방법은 자격 증명을 삽입하라는 메시지가 표시되는 것입니다. 이것은 앞에서 제안한대로 사용자 이름을 전달할 때 발생합니다 ( -u USERNAME).

그러나 사용자 이름을 그런 식으로 전달할 수 없다면 어떻게해야합니까? 예를 들어, 사용자 이름은 URL의 일부 여야하고 비밀번호 만 json 페이로드의 일부 여야합니다.

tl; dr : 이 경우 curl을 안전하게 사용하는 방법입니다.

read -p "Username: " U; read -sp "Password: " P; curl --request POST -d "{\"password\":\"${P}\"}" https://example.com/login/${U}; unset P U

read 명령 행에서 사용자 이름과 비밀번호를 입력하라는 메시지가 표시되고 제출 된 값을 후속 명령에서 참조 할 수있는 두 변수에 저장하고 마지막으로 설정을 해제합니다.

다른 솔루션이 이상적이지 않은 이유에 대해 자세히 설명하겠습니다.

환경 변수가 안전하지 않은 이유

  1. 환경이 프로세스에 내재적으로 사용 가능하므로 환경 변수 컨텐츠의 액세스 및 노출 모드를 추적 할 수 없습니다 (ps -eww).
  2. 종종 앱은 전체 환경을 파악하고 디버깅 또는 모니터링 목적으로 로그합니다 (때로는 앱 충돌 후 디스크의 일반 텍스트 로그 파일에 기록됨)
  3. 환경 변수는 하위 프로세스로 전달되므로 (최소 권한의 원칙을 위반 함)
  4. 그것들을 유지하는 것은 문제이다 : 새로운 엔지니어들은 그들이 존재하는 것을 알지 못하고 그들 주위의 요구 사항을 알지 못한다 (예를 들어, 서브 프로세스로 넘겨서는 안된다)-강제 또는 문서화되지 않았기 때문이다.

명령 행에서 직접 명령을 입력하는 것이 안전하지 않은 이유 비밀 ps -aux은 현재 실행중인 각 프로세스에 대해 제출 된 명령을 나열한 이후 실행중인 다른 사용자가 볼 수 있기 때문입니다. 또한 secrte가 bash 기록 (쉘이 종료되면)으로 끝납니다.

파일을 로컬 파일에 포함시키는 것이 안전하지 않은 이유 파일에 대한 엄격한 POSIX 액세스 제한으로 인해이 시나리오에서 위험을 완화 할 수 있습니다. 그러나이 파일은 여전히 ​​파일 시스템의 파일이며, 암호화되지 않은 상태입니다.


2
이 방법으로 프로세스 목록에 여전히 비밀번호가 표시되는 것 같습니다.
Mark Ribau

4

나는 bash (Ubuntu 16.04 LTS)에 동일한 요구가 있었고 대답에 제공된 명령이 내 경우에는 작동하지 않았습니다. 나는 사용해야했다 :

curl -X POST -F 'username="$USER"' -F 'password="$PASS"' "http://api.somesite.com/test/blah?something=123"

-F인수에 큰 따옴표는 변수를 사용하는 경우에만 필요하므로 명령 행에서 ... -F 'username=myuser' ...좋습니다.

관련 보안 공지 : Mark Ribau 씨 가 언급 한대로이 명령은 프로세스 목록 에 비밀번호 ($ PASS 변수, 확장)를 표시합니다!


1
여전히 프로세스 목록에 $ PASS 값이 표시됩니까?
Mark Ribau

네, 불행히도 그렇습니다.
Marco

1

Gnome 키링 앱이있는 시스템을 사용하는 경우 비밀번호를 직접 노출하지 않는 솔루션은 gkeyring.py 를 사용 하여 키링에서 비밀번호를 추출하는 것입니다.

server=server.example.com
file=path/to/my/file
user=my_user_name
pass=$(gkeyring.py -k login -tnetwork -p user=$user,server=$server -1)

curl -u $user:$pass ftps://$server/$file -O

1
참고 : 프로세스 목록에 비밀번호가 표시됩니다. (그리고 이것이 스크립트의 일부가 아닌 경우 역사.)
Mark

1

이것은 OP가 요청한 것보다 훨씬 많지만 비밀번호를 (으)로 안전하게 전달한 최고의 결과이므로 curl여기를 찾는 사람들을 위해 여기에 솔루션을 추가하고 있습니다.


참고 : 명령에 -s대한 arg read는 POSIX가 아니므로 어디에서나 사용할 수 없으므로 아래에서 사용되지 않습니다. 우리는 사용할 것이다stty -echo 하고 stty echo대신.

참고 : 아래의 모든 bash 변수는 함수가 아닌 설정하지 않고 로컬로 선언 될 수 있습니다.

참고 : perl반면에, 나는 그것으로 인해 많은 것들에 대한 종속성 인에 시도한 모든 시스템에서 매우 일반적으로 사용 가능 ruby하고 python그렇게 사용하지 않습니다 perl여기. 당신은 보장 할 수 있다면 ruby/ python당신이하고있는 경우, 당신은 대체 할 수있는 perl자신의 동등한 명령을 사용합니다.

참고 : bashmacOS 10.14.4의 3.2.57에서 테스트되었습니다 . 다른 쉘 / 설치에 대해서는 약간의 번역이 필요할 수 있습니다.


컬에 전달할 (재사용 가능한) 비밀번호를 사용자에게 안전하게 묻습니다. curl을 여러 번 호출해야 할 경우 특히 유용합니다.

최신 쉘의 echo경우 내장 위치 는 다음을 통해 확인하십시오 (을 통해 확인 which echo).

url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
read pass
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input
echo ${pass} | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
unset username
unset pass

구형 쉘의 경우 (프로세스 목록에서 에코가 표시되는 위치) echo와 같은 /bin/echo위치 :
이 버전비밀번호를 재사용 할 수 없습니다 . 대신 아래를 참조하십시오.

url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
perl -e '
    my $val=<STDIN>;
    chomp $val;
    print STDERR "\n";  # we need to move the line ahead, but not send a newline down the pipe
    print $val;
' | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
stty echo   # re-enable echoing user input
unset username



암호를 파일에 임시로 저장해야하는 경우 암호를 지우기 전에 여러 명령에 암호를 다시 사용해야합니다 (예 : 코드 재사용을위한 기능을 사용하고 코드를 반복하고 싶지 않으며 코드를 반복하고 싶지 않기 때문에) echo를 통해 값을 전달하십시오. (예, 이들은 다른 라이브러리에서 함수가 아닌이 형식으로 보는 데 약간의 노력을 기울였습니다. 표시하는 데 필요한 최소 코드로 축소하려고했습니다.)

에코가 내장 된 경우 (에코는 내장되어 있지만 완전성을 제공하기 때문에 특히 고려됩니다) :

url='https://example.com'
filepath="$(mktemp)"  # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
read pass
echo "${pass}" > "${filepath}"
unset pass
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input

cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-

rm "${filepath}"  # don't forget to delete the file when done!!
unset username

echo가 다음과 같은 경우 /bin/echo:

url='https://example.com'
filepath="$(mktemp)"  # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
$(perl -e '
    my $val=<STDIN>;
    chomp $val;
    open(my $fh, ">", $ARGV[0]) or die "Could not open file \"$ARGV[0]\" $\!";
    print $fh $val;
    close $fh;
' "$filepath")
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input

cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-

rm "${filepath}"  # don't forget to delete the file when done!!
unset username
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.