KISA 제보 취약점(KVE-2026-1914/1919/2019/2029/2041/2042/2043/2044)과 그 수정 과정에서 드러난 자격증명 전송로 결함을 함께 해소한다. globalHeaders 는 데이터소스와 apiCall 핸들러에만 적용되는데, 코어 ApiClient 를 직접 부르는 경로들이 그 사실을 모른 채 게이트된 엔드포인트를 호출하고 있었다. 서버는 정당한 사용자를 거부하고 화면은 이미 버튼을 내준 뒤라, 예외도 로그도 없이 그 자리만 비는 형태로만 드러났다. 전송로 10축을 전수 열거해 6건을 고치고, 같은 실수가 반복되지 않도록 규정과 coverage 에 등재했다. 아웃바운드 프록시가 사이트 자기 자신으로 가는 내부 요청까지 가로채 저장이 수십 초씩 걸리던 문제도 함께 고쳤다. 실패가 폴백으로 삼켜져 화면에는 지연으로만 나타났다.
61 lines
2.3 KiB
PHP
61 lines
2.3 KiB
PHP
<?php
|
|
|
|
/**
|
|
* 인스톨러 .env 값 직렬화 정책.
|
|
*
|
|
* `.env` 는 줄 단위 형식이라 값에 개행이 섞이면 그 뒤가 새로운 환경변수 줄로 해석된다.
|
|
* 그래서 사용자 입력에서 온 모든 값은 이 파일의 serializeEnvValue() 한 관문을 지난다.
|
|
* 관문이 하나면 나중에 필드가 늘어도 그 값이 자동으로 같은 검사를 받는다.
|
|
*
|
|
* 개행을 조용히 지우지 않고 예외로 거부하는 이유: 삭제하면 운영자가 입력한 값과 실제로
|
|
* 저장된 값이 달라지는데 그 사실이 화면에 나타나지 않는다. 정상 입력에는 개행이 들어갈
|
|
* 일이 없으므로 거부가 안전한 기본값이다. (KVE-2026-2042)
|
|
*
|
|
* 이 파일은 의존성이 없어야 한다 — 인스톨러 본 흐름(functions.php)과 설치 워커
|
|
* (installer-runtime.php) 양쪽에서 단독으로 require 된다.
|
|
*/
|
|
if (! function_exists('installer_env_value_is_single_line')) {
|
|
/**
|
|
* 값이 한 줄인지(개행·NUL 이 없는지) 확인합니다.
|
|
*
|
|
* 서버측 사전 거부(폼 검증)에서 예외를 던지지 않고 판정만 필요할 때 씁니다.
|
|
*
|
|
* @param string $value 검사할 값
|
|
* @return bool 개행·NUL 이 없으면 true
|
|
*/
|
|
function installer_env_value_is_single_line(string $value): bool
|
|
{
|
|
return strpbrk($value, "\r\n\0") === false;
|
|
}
|
|
}
|
|
|
|
if (! function_exists('serializeEnvValue')) {
|
|
/**
|
|
* .env 에 기록할 값을 직렬화합니다.
|
|
*
|
|
* CR/LF/NUL 이 포함되면 InvalidArgumentException 을 던집니다(조용한 삭제 금지).
|
|
* 그 외에는 백슬래시·큰따옴표를 이스케이프하고 큰따옴표로 감쌉니다.
|
|
*
|
|
* @param string $value 직렬화할 값
|
|
* @return string 큰따옴표로 감싼 값
|
|
*
|
|
* @throws InvalidArgumentException 값에 개행 또는 NUL 이 포함된 경우
|
|
*/
|
|
function serializeEnvValue(string $value): string
|
|
{
|
|
if (! installer_env_value_is_single_line($value)) {
|
|
throw new InvalidArgumentException(
|
|
'Environment values must not contain line breaks or NUL bytes.'
|
|
);
|
|
}
|
|
|
|
if ($value === '') {
|
|
return '""';
|
|
}
|
|
|
|
$escaped = str_replace(['\\', '"'], ['\\\\', '\\"'], $value);
|
|
|
|
return '"'.$escaped.'"';
|
|
}
|
|
}
|