bigo
값에 대해 전각 문자 처리, 잘못된 % 인코딩, XSS 보안 위험, URL 유효성 등 모든 요소를 종합적으로 검사하고 정리해주는 validation 함수를 만들어 보죠. 이는 어떤 입력이 들어와도 JSON 직렬화, 서버 전송, 화면 출력에 안전하도록 만들어 보죠.
비고 텍스트 필드 유효성 검사 함수
사용자 입력으로 들어오는 비고(bigo
) 필드를 처리할 때는 입력 문자열을 안전하게 정리하여 서버로 전송해야 합니다. 본 함수는 다음과 같은 과정을 거쳐 입력값을 검사·변환합니다:
- 전각(全角) 문자 → 반각(半角) 변환: 전각 알파벳·숫자·특수문자를 대응하는 반각 문자로 변환합니다.
- 잘못된 URI 인코딩 방지:
%
기호로 시작하는 잘못된 인코딩(%
단독, %심
, %2
등)이 있을 경우, decodeURIComponent
시 오류가 발생하지 않도록 처리합니다.
- XSS 위험 제거: 입력 문자열에 포함된
<script>
태그나 javascript:
같은 XSS 스크립트 코드를 제거합니다.
- URL 검증: 문자열에 URL이 포함되면
new URL()
로 검증하여 유효성을 확인하고, 허용된 프로토콜(http
, https
)이 아니면 제거합니다.
- 불필요 공백/특수문자 정리: 연속된 줄바꿈 또는 여러 공백을 하나로 줄이고, 과도한 특수문자 반복도 적절히 축소합니다.
- 최종 출력은 JSON 직렬화나 서버 전송 시 문제가 없는 “안전한 문자열”로 반환되며, 필요 시 경고를
console.warn()
으로 남깁니다.
아래 구현 예제와 설명, 테스트를 참고하세요.
전각 문자 변환
한글 입력 환경에서 전각 문자(예: 전각 영문자, 전각 숫자, 전각 특수기호)가 입력될 수 있습니다. 이들을 모두 반각으로 변환해야 합니다. JavaScript에서는 정규표현식과 문자코드 조작으로 쉽게 처리할 수 있습니다. 예를 들어, 유니코드 U+FF01(‘!’)부터 U+FF5E(‘~’)까지의 전각 문자를 그 문자 코드에서 0xFEE0
(65248)만큼 빼면 대응하는 반각 문자 코드가 됩니다. 또한 전각 공백(\u3000
)은 반각 공백(\u0020
)으로 교체합니다.
// 예시: 전각문자를 반각으로 변환하는 함수
function toHalfWidth(str) {
return str
// U+FF01–U+FF5E 범위의 전각 문자를 대응 반각으로 변환
.replace(/[\uff01-\uff5e]/g, ch =>
String.fromCharCode(ch.charCodeAt(0) - 0xFEE0))
// 전각 스페이스(\u3000)를 일반 스페이스(\u0020)로 변경
.replace(/\u3000/g, '\u0020');
}
// 사용 예
console.log(toHalfWidth("ABC123!@#")); // => "ABC123!@#"
위 코드와 같이 /[\uff01-\uff5e]/g
정규표현식과 charCode
연산을 이용하면 전각 기호들을 모두 대응하는 반각 문자로 변환할 수 있습니다.
잘못된 URI 인코딩 방지
사용자가 입력한 문자열에 %
문자가 포함될 때, 뒤따르는 문자가 유효한 16진수 두 자리인지 검사해야 합니다. 잘못된 인코딩(예: %
단독, %2
, %심
등)이 들어오면 decodeURIComponent
호출 시 URIError: malformed URI sequence
에러가 발생할 수 있습니다. 이를 막기 위해 정규표현식을 사용하여 %
로 시작하는 유효한 16진수 시퀀스(예: %xx
)만을 골라 decodeURIComponent
로 변환하고, 에러가 나는 경우 해당 시퀀스는 그대로 두도록 합니다. 예를 들어:
// %xx 형태의 인코딩만 안전하게 디코딩하는 예시
input = input.replace(/(%[0-9A-Fa-f]{2})+/g, seq => {
try {
return decodeURIComponent(seq);
} catch (e) {
console.warn(`Invalid escape sequence: ${seq}`);
return seq;
}
});
위 코드처럼 try/catch
로 감싸면 잘못된 %
시퀀스는 건너뛰고 정상적인 시퀀스만 디코딩할 수 있습니다. (StackOverflow에서도 이와 같은 패턴을 제안합니다.) 필요시 더 간단히 모든 %
를 사전 처리(%
→ %25
)하는 방법도 있지만, 위 패턴이 개별 시퀀스를 안전하게 처리하는 일반적인 방법입니다.
XSS 위험 요소 제거
입력 문자열에 <script>
태그나 javascript:
URI 등 XSS 공격 벡터가 포함되지 않도록 필터링해야 합니다. 기본적으로 HTML로 취급되어 실행되는 <script>
태그는 제거하고, javascript:
같은 스킴도 삭제합니다. 예를 들어, 정규표현식 /\<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi
를 사용하면 <script> ... </script>
블록 전체를 제거할 수 있습니다. 또한 "javascript:"
패턴은 /javascript:/gi
로 찾아 빈 문자열로 대체합니다.
MDN에서는 *“Sanitization is the process of removing unsafe features from a string of HTML: for example, <script>
tags or inline event handlers”*라고 언급하며, <script>
태그 등의 위험 요소 제거를 XSS 방지 조치로 권장하고 있습니다. 따라서 함수에서 입력값에 대해 이러한 치환/제거 작업을 수행해 주어야 합니다.
URL 포함 시 검증
입력에 URL이 포함될 경우, 이를 검증하여 허용된 프로토콜인지 확인합니다. 예를 들어 http://example.com
이나 https://example.com
은 허용하되, ftp:
, javascript:
등은 거릅니다. JavaScript의 URL
생성자를 사용하면 문자열이 올바른 URL 형식인지 검사할 수 있습니다. 다음과 같은 함수가 자주 쓰입니다:
function isValidHttpUrl(string) {
try {
new URL(string);
} catch (_) {
return false;
}
return (url.protocol === "http:" || url.protocol === "https:");
}
URL이 검증에 통과하지 못하면 해당 URL을 통째로 제거하거나 메시지를 경고하도록 처리합니다. 예를 들어 입력 텍스트에서 http://
또는 https://
로 시작하는 패턴이 발견되면 new URL()
로 검사하고, 프로토콜이 http:
또는 https:
인지 확인합니다. 그렇지 않으면 console.warn
으로 경고하고 해당 부분을 공백 또는 빈 문자열로 대체합니다.
공백 줄·특수문자 정리
마지막으로, 입력 내 불필요한 공백이나 특수문자 남용을 정리합니다. 예를 들어, 여러 줄 바꿈이 연속될 경우 하나의 줄 바꿈으로 줄이고, 연속된 다수의 공백이나 탭도 하나로 축소합니다. 간단한 정규표현식으로 다음과 같은 처리가 가능합니다:
// 연속된 공백(스페이스·탭)을 한 칸으로 축소
text = text.replace(/\s{2,}/g, ' ');
// 연속된 줄바꿈(빈 줄)이 두 줄 이상이면 한 줄로 축소
text = text.replace(/\n\s*\n/g, '\n');
위 코드처럼 /\s{2,}/g
를 사용하면 연속된 공백을 하나로 줄일 수 있고, /\n\s*\n/g
는 빈 줄이 여러 개 연속될 때 한 개로 줄여줍니다. 필요에 따라 전후 공백을 .trim()
으로 제거할 수도 있습니다.
전체 구현 예제
위의 설계를 반영한 JavaScript 함수 예시는 다음과 같습니다:
function validateBigo(input) {
// 1) 문자열 타입 확인
if (typeof input !== 'string') {
console.warn('Input is not a string.');
return '';
}
let text = input;
// 2) 전각 문자 → 반각 변환
text = text
.replace(/[\uff01-\uff5e]/g, ch =>
String.fromCharCode(ch.charCodeAt(0) - 0xFEE0))
.replace(/\u3000/g, '\u0020');
// 3) 잘못된 URI 인코딩 방지: %xx 패턴만 디코딩 시도
text = text.replace(/(%[0-9A-Fa-f]{2})+/g, seq => {
try {
return decodeURIComponent(seq);
} catch (e) {
console.warn(`Invalid escape sequence: ${seq}`);
return seq;
}
});
// 4) XSS 위험 요소 제거: <script> 태그 및 javascript: 스킴 삭제
text = text.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
text = text.replace(/javascript:/gi, '');
// 5) URL 포함 시 유효성 검사: http/https 외 제거
text = text.replace(/https?:\/\/[^\s]+/g, url => {
try {
let obj = new URL(url);
if (obj.protocol === 'http:' || obj.protocol === 'https:') {
return url;
} else {
console.warn(`Unsupported URL protocol: ${url}`);
return '';
}
} catch {
console.warn(`Malformed URL: ${url}`);
return '';
}
});
// 6) 공백 및 특수문자 정리: 연속 공백·줄바꿈 축소, trim
text = text.replace(/\s{2,}/g, ' ');
text = text.replace(/\n\s*\n/g, '\n');
text = text.trim();
return text;
}
// === 사용 예시 ===
const example = "HTTP://예제.컴 \n<script>alert('XSS');</script>\n\n 테스트 ";
console.log(validateBigo(example));
// 출력 예: "HTTP://예제.컴 테스트"
위 함수는 입력형 검사 → 전각변환 → URI디코딩 → 스크립트 제거 → URL검증 → 공백정리 순서로 처리합니다. 코드 내 각 단계는 앞서 설명한 방식과 일치하며, 예제에서도 한글 도메인 등이 그대로 남고 <script>
와 과도한 공백이 제거된 것을 확인할 수 있습니다.
테스트 케이스
아래는 여러 입력에 대한 테스트 예시입니다:
console.log(validateBigo("ABC abc !! "));
// 예상 출력: "ABC abc !!" (전각 문자와 공백 정리)
console.log(validateBigo("Hello%20World%3"));
// 경고: Invalid escape sequence: %3
// 예상 출력: "Hello%20World%3" (% 인코딩 오류 부분 보존)
console.log(validateBigo("<script>evil()</script>Safe"));
// 예상 출력: "Safe" (<script> 제거)
console.log(validateBigo("Click <a href=\"javascript:alert(1)\">here</a>"));
// 예상 출력: "Click <a href=\"\">here</a>" 또는 "Click here"
// (javascript: 제거)
console.log(validateBigo("Visit http://example.com and ftp://files"));
// 경고: Unsupported URL protocol: ftp://files
// 예상 출력: "Visit http://example.com and " (ftp URL 제거)
console.log(validateBigo("\n\nLine1\n\n\nLine2 \t\t"));
// 예상 출력: "Line1\nLine2" (연속 줄바꿈과 공백 정리)
각 테스트에서 보듯, 유효성 검사 함수는 입력 문자열에서 문제되는 부분을 안전하게 제거하거나 경고합니다. 최종 반환값은 JSON으로 직렬화해도 오류가 없는 일반 텍스트 문자열입니다.
참고자료: JavaScript를 이용한 전각-반각 변환 예제, decodeURIComponent
예외 처리 방법, URL 검증 방법, 공백 정리 정규표현식 예, 그리고 XSS sanitization 설명 등을 참고하여 구현하였습니다.