fpfile로부터 HTTP 프록시 인증 정보를 읽도록 Firefox 커스텀하기
요약
Firefox 소스 코드를 수정하여 명령줄 인자인 --fpfile로부터 HTTP 프록시 인증 정보를 자동으로 읽어오는 방법을 설명합니다. 자동화된 환경에서 대화형 프롬프트 없이 인증을 처리할 수 있는 커스텀 빌드 가이드를 제공합니다.
핵심 포인트
- --fpfile 인자를 통한 프록시 인증 자동화 구현
- nsHttpChannelAuthProvider.cpp 파일 수정 필요
- 파일 로드 실패 시 기존의 대화형 프롬프트로 폴백
- C++ 기반의 Firefox 소스 코드 커스텀 기술
fpfile로부터 HTTP 프록시 인증 정보를 읽도록 Firefox 커스텀하기
함께 배우고, 공유하고, 토론하기 위해 저의 Discord 커뮤니티에 참여하세요: https://discord.gg/rX2vkNNW
이 글은 HTTP 프록시 인증 (HTTP proxy authentication)을 위한 작은 Firefox 소스 코드 커스텀에 대해 설명합니다.
목표는 간단합니다. Firefox가 비밀번호로 보호된 프록시로부터 HTTP 인증 챌린지 (HTTP authentication challenge)를 받으면, 먼저 --fpfile 명령줄 인자 (command-line argument)를 통해 전달된 로컬 fpfile에서 사용자 이름과 비밀번호를 읽으려고 시도합니다. 만약 파일이 없거나, 읽을 수 없거나, 불완전한 경우, Firefox는 원래의 사용자 이름/비밀번호 입력창 (prompt)으로 돌아갑니다.
이는 프록시 인증 정보가 대화형 대화창 (interactive dialog) 대신 로컬 런타임 설정 (runtime configuration)에 의해 제공되어야 하는 자동화되거나 커스텀된 Firefox 빌드를 실행할 때 유용합니다.
수정된 파일
핵심 변경 사항은 다음 파일에 있습니다:
C:\firefox\firefox\netwerk\protocol\http\nsHttpChannelAuthProvider.cpp
Firefox는 HTTP 인증 챌린지에 대한 인증 정보가 필요할 때 nsHttpChannelAuthProvider::GetCredentialsForChallenge()에 진입합니다. 407 Proxy Authentication Required와 같은 프록시 챌린지도 이 경로를 거칩니다.
원래 Firefox는 인증 정보가 필요할 때 PromptForIdentity()를 직접 호출했습니다. 커스텀된 버전은 먼저 --fpfile로 지정된 파일에서 인증 정보를 로드하려고 시도합니다. 해당 시도가 실패할 경우에만 원래의 입력창을 호출합니다.
새로운 Include
파일 상단 근처에 몇 가지 include가 추가되었습니다:
#include <fstream>
#include <string>
...
이 HTTP 프록시 인증 변경을 위해 중요한 것들은 다음과 같습니다:
#include <fstream>
#include <string>
#include "base/command_line.h"
이것들은 로컬 fpfile을 읽고, 텍스트를 파싱하며, 현재 프로세스의 명령줄 인자 (command-line arguments)에 접근하는 데 사용됩니다.
로직이 위치한 곳
새로운 로직은 Firefox가 이전에 인증 정보를 요청하던 영역 주변인 GetCredentialsForChallenge() 내부에 배치되었습니다.
원래의 흐름은 다음과 같았습니다:
rv = PromptForIdentity(level, proxyAuth, realm, aAuthType, authFlags, *ident);
if (NS_FAILED(rv)) return rv;
identFromURI = false;
커스텀된 흐름은 다음과 같습니다:
- Firefox 프로세스가
--fpfile옵션과 함께 시작되었는지 확인합니다. - 만약 그렇다면, 해당 파일을 엽니다.
httpauth.username과httpauth.password를 읽습니다.- 두 값이 모두 존재하면,
nsHttpAuthIdentity를 생성합니다. - 만약 어떤 단계에서든 실패하면, Firefox의 기존 프롬프트(Prompt) 동작을 계속 수행합니다.
fpfile로부터 HTTP 인증 정보(HTTP Auth Credentials) 읽기
코드는 먼저 현재 Firefox 프로세스에 fpfile 스위치가 있는지 확인합니다:
const char kRuyiFileSwitch[] = "fpfile";
if (CommandLine::ForCurrentProcess()->HasSwitch(UTF8ToWide(kRuyiFileSwitch))) {
std::wstring fpValue =
...
스위치에 값이 있으면, 해당 경로를 UTF-8로 변환하여 엽니다:
if (!fpValue.empty()) {
std::string fileName = WideToUTF8(fpValue);
std::fstream fs(fileName, std::ios::in);
...
그 다음 파일을 한 줄씩 읽습니다. :와 = 모두 구분자(Separator)로 허용됩니다:
std::string line;
std::string username;
std::string password;
...
키(Key)와 값(Value)은 트리밍(Trimmed) 처리되므로, 주변의 공백이나 탭이 있어도 허용됩니다:
size_t keyStart = key.find_first_not_of(" \t");
if (keyStart == std::string::npos) {
continue;
...
오직 두 개의 키만 인식됩니다:
if (key == "httpauth.username") {
username = value;
} else if (key == "httpauth.password") {
...
두 값이 모두 존재할 때, Firefox는 HTTP 인증 식별자(HTTP authentication identity)를 생성합니다:
if (!username.empty() && !password.empty()) {
*ident = nsHttpAuthIdentity(
EmptyString(), NS_ConvertUTF8toUTF16(username),
...
첫 번째 필드인 EmptyString()은 도메인(Domain)입니다. 다음 두 필드는 사용자 이름(Username)과 비밀번호(Password)입니다.
Firefox의 기존 프롬프트로 폴백(Falling Back)
--fpfile이 제공되지 않거나, 파일을 열 수 없거나, 필드가 누락되었거나, 또는 인증 정보 중 하나라도 비어 있는 경우 ident는 빈 상태로 유지됩니다. 이 경우 Firefox는 기존의 동작을 유지하며 사용자에게 프롬프트를 표시합니다:
if (ident->IsEmpty()) {
rv = PromptForIdentity(level, proxyAuth, realm, aAuthType, authFlags,
*ident);
...
실제 동작은 다음과 같습니다:
- fpfile에
httpauth.username과httpauth.password가 모두 포함되어 있으면, Firefox는 프롬프트를 표시하지 않고 자동으로 인증합니다. - fpfile이 누락되었거나, 읽을 수 없거나, 불완전한 경우, Firefox는 이전과 정확히 동일하게 동작하며 사용자 이름/비밀번호 대화 상자를 표시합니다.
fpfile 형식
Firefox를 다음과 같이 실행합니다:
--fpfile=C:\firefox\fp.txt
fpfile은 =를 사용할 수 있습니다:
httpauth.username=your_user
httpauth.password=your_password
또한 :를 사용할 수도 있습니다:
httpauth.username: your_user
httpauth.password: your_password
실제 인증 정보는 로컬 fpfile에서만 사용하십시오. 운영 환경의 프록시(Proxy) 비밀번호를 문서, 코드 주석, 커밋, 스크린샷 또는 블로그 포스트에 포함하지 마십시오.
중요한 동작 및 제한 사항
이 구현은 하나의 전역(Global) HTTP 인증 사용자 이름/비밀번호 쌍을 사용합니다. 현재 프록시 호스트(Proxy host)나 포트(Port)에 따라 인증 정보를 매칭하지는 않습니다.
또한 주입된 인증 정보를 proxyAuth == true로 제한하지 않습니다. 이는 동일한 인증 경로에 도달하는 일반 웹사이트의 HTTP 기본 인증(Basic Authentication) 또는 다이제스트 인증(Digest Authentication) 요청도 이 httpauth.* 신원(Identity)을 받을 수 있음을 의미합니다.
더욱 견고한 운영 설계를 위해서는 최소 두 가지의 추가 방어 기제를 추가하겠습니다:
proxyAuth == true인 경우에만 fpfile 인증 정보를 적용합니다.- 단일 전역 쌍을 사용하는 대신 프록시 호스트와 포트에 따라 인증 정보의 범위를 지정(Scope)합니다.
이 접근 방식을 선택한 이유
주된 이점은 변경 사항이 국소적이며, 폴백(Fallback) 경로로서 Firefox의 기본 동작을 보존한다는 점입니다.
유효한 fpfile 인증 정보가 있는 경우, 커스텀 빌드는 대화형 프록시 인증 프롬프트(interactive proxy credential prompt) 없이 실행될 수 있습니다. 동시에, 파일이 없거나 유효하지 않은 경우에는 일반적인 Firefox 동작이 그대로 유지됩니다.
이를 통해 런타임 설정(runtime configuration)을 프로필(profile) 외부에 유지할 수 있으며, Firefox 설정(preferences)에 프록시 인증 정보를 저장하는 것을 방지할 수 있습니다.
요약 (Summary)
이 커스텀 설정은 프록시 인증 정보(proxy credentials)를 로컬 --fpfile 설정 파일을 통해 제공할 수 있도록 Firefox의 HTTP 인증 흐름(HTTP authentication flow)을 변경합니다.
주요 사항은 다음과 같습니다:
- 변경 사항은
nsHttpChannelAuthProvider.cpp에 적용됩니다. - 코드는
--fpfile로부터httpauth.username및httpauth.password를 읽어옵니다. - 두 값이 모두 존재할 때만
nsHttpAuthIdentity를 생성합니다. - 읽기에 실패하면, Firefox는
PromptForIdentity()로 폴백(fallback)합니다. - 실제 비밀번호는 공개 문서가 아닌 로컬 fpfile에 보관되어야 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기