+ 핵심 위험과 간헐적 실패 원인을 간결히 연결했다.
- 테스트 제안과 코드 품질·성능 검토가 다소 얕다.
코드를 붙여 넣으면 코드 품질, 버그 가능성, 보안 취약점, 성능 병목, 모범 사례와 테스트 보완점을 항목별로 검토합니다.
| 분류 | 개발 › 코딩 |
|---|---|
| 태그 | 검토분석개발자코드 |
You are an expert AI code reviewer. When I share code with you, analyze it thoroughly and provide: ## Code Quality - Identify code smells, anti-patterns, and areas for improvement - Suggest refactoring opportunities - Check for proper naming conventions and code organization ## Bug Detection - Find potential bugs and logic errors - Identify edge cases that may not be handled - Check for null/undefined handling ## Security Analysis - Identify security vulnerabilities (SQL injection, XSS, etc.) - Check for proper input validation - Review authentication/authorization patterns ## Performance - Identify performance bottlenecks - Suggest optimizations - Check for memory leaks or resource issues ## Best Practices - Verify adherence to language-specific best practices - Check for proper error handling - Review test coverage suggestions Provide your review in a clear, actionable format with specific line references and code suggestions where applicable.
공유한 코드의 문제와 개선점을 실행 가능한 형식으로 받고 싶을 때 쓰는 리뷰 프롬프트다. 가능한 경우 줄 번호와 코드 제안을 포함하도록 요구한다.
Gemini는 가장 포괄적이지만 장황하고 일부 과장이 있다. ChatGPT는 정확성과 분량의 균형이 가장 좋으며, [C]는 답이 없다.
+ 핵심 위험과 간헐적 실패 원인을 간결히 연결했다.
- 테스트 제안과 코드 품질·성능 검토가 다소 얕다.
+ 보안·버그·성능과 개선 코드를 폭넓게 다뤘다.
- 일부 원인을 단정하고 성능 설명도 다소 과장됐다.
| 기준 | ChatGPT | Gemini | 앞선 모델 |
|---|---|---|---|
| 지시 준수 | 8 | 9 | Gemini +13% |
| 정확성 | 9 | 8 | ChatGPT +13% |
| 구체성 | 9 | 9 | 동점 |
| 구성·가독성 | 9 | 9 | 동점 |
| 분량 적정성 | 9 | 6 | ChatGPT +50% |
gpt-5.6-sol가 모델 이름을 가린 채 1~10점으로 채점했습니다 (2026-09-24). 측정값이 아니라 AI 심사 결과입니다.
같은 입력을 세 모델에 넣어 받은 답을 그대로 옮겼습니다. 각 CLI(에이전트 하네스)에서 실행했습니다. ChatGPT·Claude 앱이나 웹에서는 답이 다를 수 있습니다.
[붙여 넣은 자료]
다음 로그인 API 코드 리뷰 부탁드립니다. Node.js + Express로 짰는데 가끔 로그인 실패 문의가 들어옵니다.
```javascript
app.post('/login', (req, res) => {
const { username, password } = req.body;
const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;
db.query(query, (err, result) => {
if (err) return res.status(500).send(err.stack);
if (result.length > 0) {
res.json({ token: jwt.sign({ id: result[0].id }, 'secret123') });
} else {
res.status(401).send('Invalid credentials');
}
});
});
```현재 코드는 SQL 인젝션과 평문 비밀번호 저장/검증 문제가 있어 즉시 수정이 필요합니다. 간헐적인 로그인 실패는 입력값 처리, 중복 사용자, DB 오류, 비밀번호 저장 방식 불일치 등에서 발생할 수 있습니다.
const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;
사용자 입력을 SQL 문자열에 직접 삽입하고 있습니다. 공격자가 SQL 조건을 조작할 수 있습니다.
' OR '1'='1
처럼 입력하면 인증 우회가 가능할 수 있습니다.
반드시 파라미터 바인딩을 사용해야 합니다.
DB에 비밀번호를 평문으로 저장하거나 SQL에서 직접 비교하는 구조는 안전하지 않습니다. 비밀번호는 bcrypt 또는 argon2로 해시하고 애플리케이션에서 검증해야 합니다.
jwt.sign({ id: result[0].id }, 'secret123')
소스 코드에 노출된 짧은 키는 위조될 수 있습니다. 환경 변수와 충분히 긴 랜덤 키를 사용하고 만료 시간도 지정해야 합니다.
return res.status(500).send(err.stack);
스택 트레이스에는 SQL, 테이블명, 경로 등 민감한 정보가 포함될 수 있습니다. 상세 오류는 서버 로그에만 기록해야 합니다.
req.body, username, password가 없거나 문자열이 아닐 수 있습니다.
username의 대소문자/공백 불일치등이 간헐적인 실패 원인이 될 수 있습니다.
username이 중복될 수 있으면 첫 번째 레코드만 사용하게 됩니다.
result[0]
username에 UNIQUE 제약을 설정해야 합니다.
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
app.post('/login', async (req, res) => {
try {
const { username, password } = req.body ?? {};
if (
typeof username !== 'string' ||
typeof password !== 'string' ||
username.trim() === '' ||
password.length === 0 ||
username.length > 100 ||
password.length > 200
) {
return res.status(400).json({
message: '아이디와 비밀번호를 확인해 주세요.'
});
}
const normalizedUsername = username.trim();
const [rows] = await db.promise().query(
'SELECT id, password_hash FROM users WHERE username = ? LIMIT 1',
[normalizedUsername]
);
const user = rows[0];
// 존재 여부를 외부에 구분해서 노출하지 않음
const isValid = user
? await bcrypt.compare(password, user.password_hash)
: false;
if (!isValid) {
return res.status(401).json({
message: '아이디 또는 비밀번호가 올바르지 않습니다.'
});
}
const token = jwt.sign(
{ sub: String(user.id) },
process.env.JWT_SECRET,
{
algorithm: 'HS256',
expiresIn: '1h'
}
);
return res.json({ token });
} catch (err) {
console.error('Login failed:', err);
return res.status(500).json({
message: '일시적인 서버 오류가 발생했습니다.'
});
}
});
비밀번호 생성 또는 변경 시:
const passwordHash = await bcrypt.hash(password, 12);
DB에는 password_hash만 저장해야 합니다.
다음 로그를 민감정보 없이 확인해 보세요.
express.json()이 라우트보다 먼저 등록되어 있는지Content-Type: application/json 여부username 존재 여부추가로 로그인 엔드포인트에는 IP/계정 기준 rate limiting, 감사 로그, HTTPS, 일반화된 오류 메시지를 적용하는 것이 좋습니다.
| 방산 CV 12개월 로드맵 프롬프트 | |
| 2046 퍼즐 게임 제작 프롬프트 | |
| React 컴포넌트 통합 프롬프트 | |
| 3D 아바타 팩토리 요구 프롬프트 | |
| 3D FPS 게임 개발 프롬프트 |