날짜 기반 URL을 사용하여 데이터를 조회하는 구조에서 발생할 수 있는 보안 취약점과 이를 방어하기 위한 방법을 다룹니다. 날짜 값이 URL에 포함되면 발생할 수 있는 위험을 알아보고, 이를 안전하게 처리하는 방법을 살펴보겠습니다.
1. SQL 인젝션 (SQL Injection)
위험: 날짜 값이 입력된 값으로 DB에서 데이터를 조회하는 경우, 사용자가 악의적인 SQL 코드를 입력하여 SQL 인젝션을 시도할 수 있습니다. 예를 들어, 아래와 같은 공격이 가능합니다:
localhost/2025-02-19' OR 1=1 --
위와 같은 값을 입력하면 SQL 쿼리에서 `OR 1=1` 조건이 성립되어 모든 데이터가 반환될 수 있습니다.
방어 방법
- 파라미터화된 쿼리 사용: 사용자 입력을 값으로만 처리하도록 파라미터화된 쿼리 또는 ORM을 사용하여 SQL 인젝션을 방지합니다.
- 입력 값 검증: 날짜 형식이 `yyyy-mm-dd` 형식으로 정확한지 확인합니다.
const query = 'SELECT * FROM data WHERE date = $1';
const values = [req.params.date];
client.query(query, values)
.then(result => {
res.json(result.rows);
})
.catch(err => {
console.error(err);
res.status(500).send('Internal Server Error');
});
2. 날짜 형식의 예측 가능성 (Predictability of Date Format)
위험: 사용자가 날짜를 입력할 수 있는 구조에서 공격자가 특정 날짜를 추측하여 데이터에 접근할 수 있습니다. 예를 들어, 과거 날짜에 대한 데이터를 조회하려는 시도가 있을 수 있습니다.
방어 방법
- 날짜 범위 제한: 사용자가 **현재 날짜 이후**나 **미래 날짜**에 대한 데이터를 요청하는 것을 제한할 수 있습니다.
- 특정 날짜 범위 제공: 과거 데이터만 제공할 수 있도록 설정할 수 있습니다.
app.get('/data/:date', (req, res) => {
const requestedDate = new Date(req.params.date);
const currentDate = new Date();
// 현재 날짜 이후의 데이터 요청을 막기
if (requestedDate > currentDate) {
return res.status(403).send('Cannot access future data');
}
// 데이터 반환 로직
res.json(getDataForDate(req.params.date));
});
3. 디렉터리 나열 및 탐색 (Directory Traversal)
위험: 공격자가 날짜를 입력할 때, URL 구조에 대해 디렉터리 탐색 공격을 시도할 수 있습니다. 예를 들어, 날짜 부분에 `/../`을 삽입하여 의도한 범위를 벗어난 데이터를 요청할 수 있습니다.
방어 방법
- 입력 값 검증: 날짜가 예상되는 형식(예: `yyyy-mm-dd`)에 맞는지 확인하고, 불법적인 문자나 패턴을 차단합니다.
- 디렉터리 탐색 문자 차단: 날짜 값에 `/`, `..`, `\` 같은 디렉터리 탐색 문자가 포함되지 않도록 처리합니다.
const datePattern = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/; // yyyy-mm-dd 형식만 허용
app.get('/data/:date', (req, res) => {
if (!datePattern.test(req.params.date)) {
return res.status(400).send('Invalid date format');
}
// 정상적인 날짜에 대해만 데이터 처리
next();
});
4. 정보 노출 (Information Disclosure)
위험: 사용자가 날짜를 입력하고 그에 맞는 데이터를 반환하는 구조에서, 날짜마다 다른 데이터가 제공되기 때문에 공격자가 특정 날짜를 추측하여 정보를 탈취할 수 있습니다.
방어 방법
- 권한 검사 추가: 중요한 데이터에 접근할 수 있는 사용자를 제한하고, 인증 없이 중요한 데이터에 접근하는 것을 방지합니다.
- 공개/비공개 데이터 구분: 공개된 데이터와 비공개 데이터를 구분하여 처리하고, 민감한 정보는 공개되지 않도록 합니다.
app.get('/data/:date', (req, res) => {
if (!hasPermission(req.user, req.params.date)) {
return res.status(403).send('Forbidden');
}
res.json(getDataForDate(req.params.date)); // 데이터 반환
});
결론
날짜를 입력받아 요청하는 방식에서 발생할 수 있는 주요 위험은 SQL 인젝션, 예측 가능한 날짜 입력, 디렉터리 탐색, 정보 노출입니다. 이를 방지하기 위해서는 다음과 같은 방어 방법을 적용해야 합니다:
- 파라미터화된 쿼리 사용
- 입력 값 검증
- 날짜 범위 제한
- 디렉터리 탐색 문자 차단
- 권한 관리 강화
이 방법들을 종합적으로 적용하면 날짜 입력을 통한 악용을 효과적으로 방지할 수 있습니다.
'Web' 카테고리의 다른 글
Emscripten을 이용한 WebAssembly(WASM) 컴파일 가이드 (0) | 2025.03.29 |
---|---|
Nginx를 사용한 리버스 프록시 설정 (0) | 2025.03.19 |
Podman 이미지 크기 줄이기 - Dockerfile 최적화 방법 (0) | 2025.02.27 |