타자 시스템을 남용하다.
12999 단어 javascriptsecurity
JavaScript는 조금 다릅니다.
타입
JavaScript에도 유형이 있습니다.변수는
undefined
및 null
와 같은 숫자, 문자열, 부울 값, 객체, 기호 및 특수 값을 가리킬 수 있습니다.동적 타자
JavaScript 변수는 C 및 Pascal과 달리 라이프 사이클 전체에 다양한 유형의 값을 저장할 수 있습니다.변수는 하나의 실행 장면의 숫자일 수도 있고 다른 실행 장면의 문자열일 수도 있다.이것은 원본 코드를 읽는 것만으로도 프로그램이 어떻게 작동하는지 분석하기 어렵다.
약한 유형
연산자 처리 값.예를 들어,
+
연산자는 두 문자열을 더하거나 연결합니다.C 및 Pascal에서는 문자열에 숫자를 추가할 수 없습니다.이 작업은 정의되지 않았으며 변수 중 하나를 다른 유형으로 변환해야 합니다.JavaScript는 일반적으로 놀라운 방식으로 작업수를 암시적으로 변환하기 위해 최선을 다합니다.
서로 다른 유형의 객체 비교
JavaScript에는 두 개의 비교 연산자가 있습니다.
엄격하게 비교(
===
) 값과 유형을 동시에 비교한다.비교한 값이 다른 유형이 있으면, 되돌아옵니다. false
이것은 우리가 비교 연산자에서 직관적으로 기대한 결과다.느슨한 비교(
==
)는 비교를 가능하게 하기 위해 동작 수를 자동으로 유니버설 형식으로 변환하려고 시도한다.전환의 규칙은 매우 복잡해서 초보자를 곤혹스럽게 할 수도 있다.누가 특수치null
가 다른 특수치undefined
와 같다고 생각합니까?동적 지침 기반 검색
JavaScript의 동적 특성을 사용하면 서로 다른 속성의 객체를 포함하여 다양한 유형의 데이터를 처리하는 알고리즘을 사용할 수 있습니다.
임의의 필드와 값을 기반으로 그룹의 대상을 검색할 수 있는 HTTP 단점을 실현하고, 유형 시스템이 코드를 최대한 통용할 수 있도록 도와주는 방법을 알아보겠습니다.이것은 서로 다른 유형의 대상과 서로 다른 유형의 검색 필드에서 그것을 다시 사용하는 데 도움을 줄 것입니다.
우리의 예는 HTTP 요청을 처리하는 세부 사항을 처리하기 위해 Express framework를 사용하지만, 코드를 이해하기 위해 익스프레스를 깊이 이해할 필요는 없습니다.
검색 예
우리의 예시에서, 우리는 사용자를 대표하는 대상 그룹을 검색할 것이다.검색 매개 변수는 검색 문자열 매개 변수로 전달됩니다.호출자는
field
매개 변수에서 대상 속성 이름을 전달하고 value
매개 변수에서 검색 값을 전달합니다.이렇게 하면 한 단점이 여러 개의 다른 검색 조건을 지원할 수 있다.예제 HTTP 요청 및 응답은 다음과 같습니다.
GET /profile?field=email&value=joe%40wiredbraincoffee.com HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Accept: */*
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 120
Connection: keep-alive
[{"email":"[email protected]","password":"coldbrew","address":"1235 Wired Brain Blvd\r\nAwesome City, MM 55555"}]
처리자
HTTP 프로세서 코드는 매우 일반적입니다.
const users = require('./users');
function readProfile(req, res) {
// Get search params
const [field, value] = getParams(req.query, ['field', 'value']);
// Find user(s)
const results = filter(users, field, value);
res.json(results);
}
먼저 별도의 모듈users
어레이를 가져옵니다.함수readProfile
는 검색 알고리즘을 실현하고 HTTP 요청과 응답 대상을 매개 변수로 하는 Express 약정에 부합한다.흥미로운 것은 여기서부터 시작된다. 우리는
field
와 value
검색 문자열 파라미터의 값을 가져오고, 이 값 검색 users
의 그룹을 사용하여 속성이 field
변수에 저장되고 값이value 변수와 같은 대상을 찾는다.효용 함수
readProfile
구현은 간단해 보이지만 대부분의 작업은 filter
함수에서 발생한다.// Return items where a field has specific value
function filter(items, field, value) {
const results = [];
for (let i = 0; i < items.length; ++i) {
if (items[i][field] == value) {
results.push(items[i]);
}
}
return results;
}
filter
함수 교체 수조의 모든 요소를 괄호 표시법으로 이름으로 대상 속성을 검색합니다.이 알고리즘은 느슨한 비교 연산자를 사용하여 대상 속성 값을 사용자가 제공한 검색 조건과 비교한다.// Retrieve array of parameters from the query string
function getParams(qs, params) {
const results = [];
for (let i = 0; i < params.length; ++i) {
const value = qs.hasOwnProperty(params[i])
? qs[params[i]]
: null;
results.push(value);
}
return results;
}
getParams
함수는 검색 문자열에서 검색 파라미터를 검색하는 과정을 간소화시켰다.그것은 매개 변수 이름의 그룹을 매개 변수로 하고 그것을 교체한다.매개 변수에 대해 검색 문자열에 존재하는지 확인하고 결과 그룹에 추가합니다.요청한 인자가 검색 문자열에 없으면 추가됩니다. null
null
는 누락된 데이터를 나타내는 특수 JavaScript 값입니다.생성된 코드는 매우 짧아서 다른 데이터 집합에 대한 검색을 실현하고 호출자가 실행할 때 제공하는 조건을 바탕으로 쉽게 다시 사용할 수 있다.
그것은 또 안전한 구멍이 하나 있다.
느슨한 비교를 남용하다
느슨한 비교 연산자는 서로 다른 유형의 값을 비교하는 데 사용되는 surprising rules 중 하나
null
와 undefined
가 같고 엄격한 비교 알고리즘은 이 두 값을 서로 다른 것으로 간주한다.Filter 함수의 비교를 살펴보겠습니다.
if (items[i][field] == value) {
만약 우리가 한 조작수가alwaysnull
이고 다른 조작수가alwaysundefined
라고 강제할 수 있다면 비교 결과는 항상true로 되돌아갈 것이다.Google HTTP 포트는 사용자 그룹의 모든 내용을 되돌려줍니다. 이로써 프로그램의 모든 사용자에 대한 민감한 정보를 공개합니다.우리가 어떻게 할 수 있겠어?
공격 페이로드
비교의 오른쪽은
getParams
함수가 되돌아오는 값이다.우리는... 검색 문자열에서 그것을 완전히 생략해서 이 값을 null
로 설정할 수 있습니다.지금 우리는 왼손을 시종일관 되돌릴 수 있는 방법이 필요하다.
undefined
undefined
는 아직 쓰지 않은 변수 및 객체 속성에 대한 자바스크립트의 특수 값입니다.필드 변수에서 참조하는 속성이 없으면 비교의 왼쪽 전체가 항상 반환됩니다undefined
.우리는 항상 물체에 어떤 속성이 존재하는지 알지 못한다.약간의 시도와 오류를 통해 부동산 이름이 될 수 없는 값을 찾기가 어렵지 않을 것이다.
성공적인 공격은 다음과 같습니다.
GET /profile?field=doesnotexist HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Accept: */*
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 364
Connection: keep-alive
[{"email":"[email protected]","password":"coldbrew","address":"1234 Wired Brain Blvd\r\nAwesome City, MM 55555"},{"email":"[email protected]","password":"coldbrew","address":"1235 Wired Brain Blvd\r\nAwesome City, MM 55555"},{"email":"[email protected]","password":"coldbrew","address":"1236 Wired Brain Blvd\r\nAwesome City, MM 55555"}]
복구
이 구멍의 근본 원인은 복구하기 어렵지 않다.
===
연산자는 undefined
와 null
를 다른 값으로 간주한다.비교는 항상false를 되돌려줍니다. 단점은 예상한 대로 users
수조에서 데이터를 되돌려주지 않습니다.이 간단한 변경은 이 구멍을 복구했지만, 우리는 할 수 없다.
더욱 신뢰할 수 있는 복구 방안
이 빈틈은 비교적 느슨하고 공격자는value 파라미터를 무시할 수 있기 때문에 이용할 수 있습니다.readProfile 함수는 오류를 반환하지 않고 잘못된 입력 데이터로 실행됩니다.
더 완전한 복구 프로그램은
===
연산자를 사용하지만, 더욱 엄격한 입력 검증을 추가했다.조회 문자열 매개변수가 다음 값이면 끝점이 HTTP 400 응답 코드로 돌아갑니다.실종되다.매개 변수를 생략하면 의외의 코드 행위를 초래할 수 있습니다.동적과 약한 유형은 우리가 원하지 않는 일을 하더라도 프로그램 작업에 오류가 없다.
유효하지 않습니다.우리는 이 값들이 예상 범위 내에 있는지 검증해야 한다.우리의 예시에서 우리는
field
매개 변수에 대해 이 동작을 실행해야 한다. 우리는 사용자 그룹의 대상이 어떤 속성을 가지고 있는지 알고 다른 값을 사용할 이유가 없다.다음은요?
이 시리즈의 다음 글은 일부 안전하지 않은 함수를 사용하여 공격자가 우리의 프로그램에서 코드를 실행할 수 있도록 하는 방법을 설명할 것이다.
Reference
이 문제에 관하여(타자 시스템을 남용하다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/marcin_hoppe/abusing-the-type-system-5cjn텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)