Data URLs
데이터 URL
데이터 URL, 즉 data : scheme가 접두사로 붙은 URL을 사용하면 콘텐츠 작성자가 작은 파일들을 문서에 인라인으로 삽입할 수 있다.
이전에는 "데이터 URI"로 알려졌으나 WHATWG에서 이 이름을 폐기했다.
<!DOCTYPE html>
<html>
<head>
<title>Data URL 예시</title>
</head>
<body>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK3RFWHRDcmVhdGlvbiBUaW1lAOhmLzIwMjItMDMtMjJUMDg6NTQ6NDQrMDA6MDAikFF7AAAAE1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAAtJREFUeNpjYMAJ/pABISBv+0wQgwI0NjQ8IZtBjU2NAYgoMDEwAAh0BJZgAAM1sAAAAASUVORK5CYII=" alt="데이터 URL로 인라인된 이미지">
</body>
</html>
참고 : 데이터 URL은 탐색을 담당하는 설정 객체의 출처를 상속받지 않고 최신 브라우저에서 고유하고 불투명한 출처로 처리된다.
데이터 URL을 사용하여 웹페이지에 이미지를 포함하면, 그 이미지는 해당 웹페이지의 출처와 상관없이 별개의 출처로 취급된다.
다른 출처의 웹페이지에서 이 이미지에 접근하려고 해도 제한된다.
이는 데이터 URL이 보안을 높이는 데 도움이 된다.
구문 Syntax
데이터 URL은 4가지 부분들로 구성되는데, 접두사(data:), 데이터 유형을 나타내는 MIME 유형, 텍스트가 아닌 경우 선택 사항인 base64 토큰, 그리고 데이터 그 자체다.
data:[<mediatype>][;base64],<data>
미디어 유형(mediatype)은 JPEG 이미지 파일의 경우 'image/jpeg'와 같은 MIME 유형 문자열이다.
만약 생략된다면, 기본값은 text/plain;charset=US-ASCII이다.
데이터에 RFC 3986에 예약된 문자로 정의된 문자가 포함되어 있거나, 공백문자 줄바꿈 문자, 또는 기타 인쇄할 수 없는 문자가 포함되어 있는 경우 해당 문자는 URL로 인코딩되어아 한다.
데이터가 텍스트인 경우 이 텍스트를 직접 포함시킬 수 있다.(포함하는 문서 유형에 따라 적절한 엔티티 또는 이스케이프 사용)
그게 아니라면, base64를 지정하여 base64로 인코딩된 이진 데이터를 포함시킬 수 있다.
데이터가 텍스트 기반인 경우, 해당 데이터를 문서에 직접 포함 시킬 수 있다.
예를 들어, HTML에서는 텍스트 내의 특수문자나 기호를 나타내기 위해 <, &at;, & 등과 같은 문자 엔티티를 사용하여 포함시킨다.
그러나 데이터가 포함된 문서의 유형에 따라 텍스트가 올바르게 표시되고 해석되도록 특정 인코딩 또는 이스케이프 방법을 사용해야 할 수 있다.
예를 들어, 이미지, 오디오, 동영상과 같은 이진 데이터(텍스트가 아닌 데이터)를 다룰 떄는 일반적으로 base64인코딩을 사용하여 텍스트 기반 형식으로 표현한다.
이진 데이터에는 유효한 텍스트 문자가 아닌 바이트가 포함될 수 있으며 직접 포함시킬 경우 문제가 발생할 수 있기 때문이다.
MIME 유형에 대한 자세한 정보는 여기 그리고 여기 에서 찾을 수 있다.
몇 가지 예 :
data:,Hello%2C%20World%21
텍스트/일반(text/plain) 데이터 Hello, World!이다.
쉼표는 %2C로 인코딩된 URL이고 공백문자는 %20으로 인코딩 된것을 확인할 수 있다.
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==
위의 base64 인코딩 버전이다.
data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E
<h1>Hello,World!</h1>가 포함된 HTML 문서다.
data:text/html,%3Cscript%3Ealert%28%27hi%27%29%3B%3C%2Fscript%3E
자바스크립트 경고를 실행하는 <script>alert('hi');</script>가 있는 HTML 문서다.
닫는 스크립트 태그는 필수다.
base64 형식으로 데이터 인코딩 Encoding data into base64 format
base64는 이진 데이터를 radix-64 표현으로 변환하여 ASCII 문자열 형식으로 나타내는 이진-텍스트 인코딩 체계 그룹이다.
ASCII 문자로만 구성된 Base64 문자열은 일반적으로 URL에 쓰기에 안전하므로 데이터 URL에서 데이터를 인코딩하는 데 사용할 수 있다.
자바스크립트에서 인코딩 Encoding in JavaScript
웹 API에는 base64로 인코딩하거나 디코딩하는 기본 메서드인 base64가 있다.
유닉스시스템에서 인코딩 Encoding on a Unix system
Linux 및 mac 시스템에서 파일 또는 문자열의 base64 인코딩은 명령줄(commend-line) Base64를 사용하여 구현할 수 있다.(혹은 대신에 -m 인수가 있는 uuencode 유틸리티를 사용하여 인코딩할 수 있다.)
echo -n hello|base64
# outputs to console: aGVsbGB=
echo -n hello>a.txt
base64 a.txt
# outputs to console: aGVsbGB=
base64 a.txt>b.txt
# outputs to file b.txt: aGVsbGB=
Microsoft 윈도우에서 인코딩 Encoding on Microsoft Windows
Windows에서는 PowerShell의 Convert.ToBase64String을 사용하여 base64 인코딩을 수행할 수 있다.
[convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("hello"))
# outputs to console: aGVsbG8=
또는 대안으로 GNU/Linux 셀(WSL와 같은)은 유틸리티 base64를 제공한다.
bash$ echo -n hello | base24
# outputs to console: aGVsbG8=
일반적인 문제 Common problems
이 섹션에서는 데이터 URL을 만들고 사용할 때, 일반적으로 발생하는 문제들에 대해 설명한다.
data:text/html,lots of text...<p><a name%30"bottom">bottom</a>?arg=val</p>
이 내용은 다음과 같은 HTML 리소스를 나타낸 것이다.
lots of text...
<p><a name-"bottom">bottom</a>?arg=val</p>
- 구문
데이터 URL의 형식은 매우 간단하지만 "데이터" 세그먼트 앞에 쉼표 넣는 것을 잊어버리거나 데이터를 base64 형식으로 잘못 인코딩 하기 쉽다.
base64 인코딩은 이진 데이터를 ASCII 문자로 변환하는 방법 중 하나다.
이 방법은 데이터를 안전하게 전송하고 저장할 수 있도록 해준다.
그러나 올바르게 사용되지 않으면 문제가 발생할 수 있다.
만약 인코딩 프로세스를 잘못 사용하거나 잘못된 방법으로 인코딩하면, 잘못된 결과가 나올 수 있다.
이러한 잘못된 인코딩은 데이터를 해독하고 처리하는데 문제를 일으킬 수 있다.
따라서 base64 인코딩을 올바르게 수행하는 것이 중요하며, 올바르게 처리하지 않으면 데이터 전송이나 해석에 문제가 발생할 수 있다.
1. 인코딩의 잘못된 적용
UTF-8로 인코딩된 텍스트 파일이 있지만 올바른 문자 집합을 지정하지 않고 실수로 base64를 사용하여 인코딩하려 시도한다고 가정해본다.
원문 : "Hello, world! 안녕하세요"
잘못 인코딩된 base64 : "SGVsbG8sIHdvcmxkISDtlbDsmIHrsJTrq5ggMTIzNDU2"
2. 인코딩 오류
UTF-8을 사용하여 문자열을 인코딩하려고 했지만 실수로 ISO-8859-1(Latin-1)과 같은 다른 문자 집합을 사용했다고 가정한다.
이로 인해 잘못된 인코딩이 발생하고 잠재적으로 잘못된 base64 데이터가 발생한다.
원문 : "Cafe"
잘못 인코딩된 base64(ISO-8859-1 사용) : "Q2Fmw6k="
올바르게 인코딩된 Base64(UTF-8 사용) : "Q2Fmw6k="
3. 손상된 데이터 : 인코딩하려는 데이터가 손상되었거나 유효하지 않은 경우 base64 출력의 결과도 유효하지 않는다.
원본 데이터 : [손상된 바이너리 데이터]
Base64로 인코딩된 출력 : [잘못된 Base64 문자]
4. 잘린 데이터
데이터의 일부만 base64로 올바르게 인코딩되면 결과 출력이 잘려서 사용할 수 없게 된다.
원본 데이터 : "Hello, world!"
첫 번째 부분인 "SGVsbG8s"만 인코딩된다.
잘린 base64 출력 : "SGVsbG8s"
이러한 예는 인코딩 프로세스 중 잘못된 적용, 오류, 손상 또는 잘림이 어떻게 잘못된 base64 데이터로 이어질 수 있는지 보여 준다.
또한, 데이터 무결성을 보장하기 위해 인코딩을 정확하게 처리하는 것이 중요하다.
- HTML 형식
데이터 URL은 파일(예 : HTML 파일) 내의 파일(예 : 이미지, 비디오, 오디오, 텍스트 등)을 제공하며, 이것은 잠재적으로 포함하는 문서의 너비에 비해 매우 넓을 수 있다.
URL로서 데이터는 공백(줄바꿈, 탭, 공백)과 함께 형식화해야 하지만 base64 인코딩을 사용할 때 발생하는 실질적인 문제가 있다.
문서의 너비에 비해 매우 넓으면 코드 에디터에서 많은 공간을 차지하기 때문에 주변 레이아웃에 영향을 줄 수 있다.
데이터의 일부가 공백을 포함하고 있을 수 있어서 공백도 함께 형식화 해야한다.
하지만 base64 인코딩을 사용한다면 매우 길어질 수 있으며, 길이 제한을 초과하거나 읽기 어렵게 만들 수 있다.
- 길이 제한
브라우저는 특정 최대 데이터 길이를 지원할 필요가 없다.
예를 들어 Opera 11 브라우저는 URL을 65535자로 제한하여 데이터 URL을 65529자로 제한한다.(65529자는 MIME 유형을 지정하지 않고 일반 데이터를 사용하는 경우 소스가 아닌 인코딩된 데이터 길이를 의미한다.)
Firefox 버전 97 이상에서는 최대 32MB에 가까운 제한이 있었다.(97 이전에는 256MB에 가까운 제한이 있었다.)
Chromium은 512MB를 초과하는 URL을, Webkit(Safari)은 2048MB를 초과하는 URL을 지원한다.
웹 브라우저의 데이터 크기에 대한 표준화된 최대 제한은 없지만 개발자는 잠재적인 실제 제한 사항을 인식하고 그에 따라 애플리케이션을 설계하여 최적의 성능과 사용자 경험을 보장해야 한다.
- 오류 처리 부족
미디어의 잘못된 매개변수 또는 'base64' 지정할 때의 오타는 무시되지만 오류는 제공되지 않는다.
데이터 URL에는 미디어 유형 (예 : text/plain, image/jpeg) 또는 인코딩 방법(예 : base64)을 지정하는 매개변수가 포함될 수 있다.
이러한 매개변수가 잘못 지정되거나 오타가 포함될 경우 브라우저는 계속 데이터 URL 처리를 시도하지만 잘못된 매개변수를 무시할 수 있다.
이런 경우, 브라우저는 사용자나 개발자에게 잘못된 매개변수가 있음을 알리는 오류 메시지나 경고를 생성하지 않는다.
오류 처리 부족으로 인해 특히 복잡한 데이터 URL로 작업할 때 문제를 식별하고 해결하기가 어려울 수 있다.
오류 처리 없이 잘못된 매개변수를 무시하면 브라우저에서 예기치 않은 동작이 발생하거나 데이터가 잘못 해석할 수 있다.
(예 : 미디어 유형을 잘못 지정하여 브라우저가 콘텐츠를 올바르게 렌더링 하지 못할 수 있으며, 인코딩 방법을 잘못 입력하면 데이터가 제대로 디코딩되지 않을 수 있다.)
오류 메시지가 없기 때문에 개발자가 데이터 URL과 관련된 문제를 진단하고 수정하기가 어렵다.
개발자는 시행착오나 외부 도구를 사용하여 데이터 URL 매개변수의 오류를 식별하고 수정해야 할 수도 있다.
요약하면, 데이터 URL의 유효하지 않은 매개변수에 대한 오류 처리 부족으로 인해 웹 애플리케이션의 데이터 표현 및 렌더링과 관련된 문제 해결이 모호해지고 어려워질 수 있다.
개발자는 다양한 브라우저와 플랫폼 간의 호환성과 안정성을 보장하기 위해 데이터 URL을 구성할 때 주의를 기울이고 매개변수의 유효성을 신중하게 확인해야 한다.
- 지원되지 않는 쿼리 문자열 등
데이터 URL의 데이터 부분은 불투명하므로 데이터 URL과 함께 쿼리 문자열(<url>?parameter-data 구문이 포함된 페이지별 매개변수)을 사용하려고 하면 URL의 나타내는 데이터에 쿼리 문자열만 포함된다.
데이터 URL 내에서 쿼리 문자열은 따로 분석되거나 별도로 처리되지 않는다.
예를 들어, 다음과 같은 데이터 URL(base64로 인코딩된 "Hello, world!" 텍스트)이 있다고 가정해본다.
data:text/plain;base64,SGVsbG8sIHdvcmxkIQ==
그러고 나서 이 데이터 URL에 쿼리 문자열을 추가한다.data:text/plain;base64,SGVsbG8sIHdvcmxkIQ==?param=value
전체 쿼리 문자열 "?param=value"이 URL이 나타내는 데이터의 일부로 간주된다.
브라우저는 이를 별도의 매개변수로 분석하지 않으며, 이 데이터의 일부로 처리한다.
따라서 데이터 URL 내에서 쿼리 문자열을 사용하려면 이를 데이터로 처리하는 방식을 애플리케이션에서 따로 처리해야 한다.
- 보안 문제
많은 보안 문제(예 : 피싱)가 데이터 URL과 연관되어 있으며 브라우저의 최상위 수준에서 해당 URL로 이동한다.
이러한 문제를 완화하기 위해 데이터에 대한 최상위 탐색에서 URL은 모든 최신 브라우저에서 차단된다.
자세한 내용은 Mozilla 보안 팀의 블로그 게시물을 참조한다.
데이터 URL은 피싱 공격과 같은 악의적인 목적으로 악용될 수 있다.
데이터 URL에는 임의의 데이터가 포함될 수 있어서, 합법적인 웹사이트를 모방하거나 사용자를 속여 중요한 정보를 공개하도록 조작될 수 있다.
'최상위 탐색'은 다른 웹페이지에 포함되지 않고 브라우저의 주소 표시줄로 직접 탐색하거나, 또는 하이퍼링크를 통해 URL로 탐색하는 것을 의미한다.
데이터 URL에 대한 최상위 탐색을 허용하면 동일 출처 정책을 우회하고 예기치 않은 동작이나 악용으로 이어질 수 있으므로 심각한 보안 위험이 발생한다.
이러한 보안 문제를 해결하기 위해 최신 브라우저는 데이터 URL에 대한 최상위 탐색을 차단하는 조치를 구현했다.
이것은 사용자가 브라우저의 주소 표시줄이나 웹 페이지의 링크를 통해 데이터 URL에 직접 액세스하는 것을 방지하여 피싱 공격 및 데이터 URL과 관련된 기타 보안 위협의 위험을 줄인다.
요약하자면, 최신 브라우저에서 데이터 URL에 대한 최상위 탐색을 차단하는 것은 잠재적인 악용 및 보안 위협으로부터 사용자를 보호하는 중요한 보안 조치이다.
개발자와 사용자는 안전한 브라우징 경험을 보장하기 위해 브라우저 공급업체가 권장하는 모범 사례 및 보안 조치에 대한 정보를 지속적으로 받아야 한다.
Data URLs - HTTP | MDN
Data URLs, URLs prefixed with the data: scheme, allow content creators to embed small files inline in documents. They were formerly known as "data URIs" until that name was retired by the WHATWG.
developer.mozilla.org