문서 작업 가이드
깨진 URL 파라미터 고치기
중첩 URL, 반복 키, 더하기 기호, 이중 인코딩 때문에 깨진 쿼리 파라미터를 구조별로 진단하고 안전하게 다시 만드는 방법을 설명합니다.
작성 및 검수 SimpleWebUtils게시일: 검토일:
이 작업 흐름을 검증한 방법
“깨진 URL 파라미터 고치기 예시” 문서 입력을 개발자 변환 워크벤치에 그대로 넣었습니다. 수행 순서는 “빈 값과 반복 키 확인하기”, “검증한 값으로 링크 다시 만들기”였고 브라우저 결과를 예시 출력과 대조했습니다. 실패 경계는 “더하기 기호를 모두 공백으로 바꾸기”, “잘못된 계층을 고치기” 두 항목으로 나눠 검토했습니다.
중첩 callback만 인코딩하자 code와 status는 redirect 안에, utm_source는 바깥 파라미터로 유지됐으며 쿼리 전체를 인코딩한 결과는 비교를 통과하지 못했습니다.
문제 상황
예약 문자가 값 안에 그대로 들어가거나, 프레임워크마다 반복 키를 다르게 처리하거나, 값을 너무 일찍 또는 두 번 인코딩하면 서버가 보낸 쪽의 의도와 다른 데이터를 받습니다. 특히 콜백 URL 안의 `&`는 값의 일부이므로 인코딩해야 하지만, 바깥 파라미터를 나누는 `&`는 구분자로 남겨야 합니다.
공식 출처와 표준
다음 공식 문서는 이 작업 흐름에서 다루는 형식과 보안 경계의 기준입니다. 도구별 실행 검증은 위에 별도로 기록합니다.
- URL Living Standard
WHATWG
이럴 때 사용하세요
- 리디렉션, 웹훅 또는 OAuth 콜백에서 파라미터가 누락되거나 중간에서 잘릴 때 사용합니다.
- 값에 `+`, `%20`, `%252F`, `%253A`가 있고 공백인지 예약 문자인지 이중 인코딩인지 구분해야 할 때 적합합니다.
- `tag=one&tag=two`처럼 같은 키가 반복되며 수신 시스템의 배열 처리 방식을 확인해야 할 때 사용합니다.
- 한 파라미터 안에 콜백 URL, 검색어 또는 JSONPath 표현식이 중첩되어 있을 때 도움이 됩니다.
단계
- 1단계
원본을 보존하고 쿼리를 표로 파싱하기
수정 전 URL을 따로 보관한 뒤 쿼리 문자열을 개발자 변환 워크벤치에서 파싱합니다. 의도하지 않은 행이 생겼다면 중첩 값 안의 `&`가 인코딩되지 않았는지 먼저 확인합니다.
- 2단계
빈 값과 반복 키 확인하기
빈 값, 이름 없는 키, 반복된 키를 모두 기록합니다. 수신 앱이 첫 값, 마지막 값 또는 전체 배열 중 무엇을 사용하는지 API 문서나 실제 요청 로그로 확인합니다.
- 3단계
의심스러운 값은 한 번만 디코딩하기
`%25`, `%2F`, `%3F`, `%26`이 포함된 값만 URL 디코더로 한 번 풉니다. 기대한 평문과 비교하고, 다음 디코딩이 정상적인 퍼센트 시퀀스를 URL 문법으로 바꾼다면 더 진행하지 않습니다.
- 4단계
검증한 값으로 링크 다시 만들기
예약 문자가 들어간 값만 인코딩해 바깥 쿼리를 다시 조립합니다. 페이지가 열리는지만 보지 말고 실제 수신 앱이나 요청 로그에서 각 키와 값이 의도대로 전달됐는지 확인합니다.
예시
깨진 URL 파라미터 고치기 예시
입력
redirect=https://app.example.com/finish?code=abc&status=ok&utm_source=email출력
redirect=https%3A%2F%2Fapp.example.com%2Ffinish%3Fcode%3Dabc%26status%3Dok&utm_source=email흔한 실수
더하기 기호를 모두 공백으로 바꾸기
`+`는 폼 디코딩 규칙에서는 공백일 수 있지만 이메일 별칭, 수식, 서명에서는 실제 더하기 기호일 수 있습니다. 대상 파서의 규칙을 확인한 뒤 값별로 처리해야 합니다.
잘못된 계층을 고치기
중첩 URL이 한 파라미터의 값이라면 그 값만 인코딩해야 합니다. URL 전체를 인코딩하면 수신기가 바깥 키를 찾는 데 필요한 구분자까지 사라집니다.
반복 키를 무조건 삭제하기
반복 키 자체는 유효할 수 있습니다. 수신 시스템이 배열, 첫 값 또는 마지막 값 중 어떤 규칙을 사용하는지 확인하지 않고 합치거나 삭제하면 의미가 달라집니다.
자주 묻는 질문
깨진 쿼리 문자열을 가장 안전하게 고치는 순서는 무엇인가요?
원본을 보존하고 키와 값으로 파싱한 뒤, 의심스러운 값만 한 번 디코딩합니다. 예약 문자가 있는 값만 다시 인코딩하고 동일한 엔드포인트가 실제로 받은 값을 비교하세요.
앰퍼샌드 뒤의 값이 왜 별도 파라미터로 바뀌나요?
값 안의 인코딩되지 않은 `&`를 파서가 새 파라미터의 시작으로 읽기 때문입니다. 중첩 값의 `&`는 인코딩하고 바깥 파라미터 구분자는 그대로 두어야 합니다.
반복되는 쿼리 키는 삭제해야 하나요?
자동으로 삭제하면 안 됩니다. 반복 키는 여러 시스템에서 유효하므로 수신 앱이 배열, 첫 값 또는 마지막 값으로 해석하는지 확인한 뒤 결정하세요.