在 Manus 中运行任何 Skill
一键导入
一键导入
一键在 Manus 中运行任何 Skill
开始使用security
星标0
分支0
更新时间2026年1月23日 02:42
보안 취약점 분석, OWASP Top 10, 인증/인가 패턴
安装
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
SKILL.md
readonly菜单
보안 취약점 분석, OWASP Top 10, 인증/인가 패턴
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
디버깅 전략, 로깅 베스트 프랙티스, 에러 추적
REST API 설계 원칙, GraphQL 패턴, API 버저닝
코드 품질 가이드, 클린 코드 원칙, 리팩토링 패턴
기술 문서 작성 가이드, 문서 유형별 템플릿
Git 작업 흐름, 커밋 메시지, 브랜치 전략 가이드
성능 최적화 패턴, 캐싱 전략, 데이터베이스 최적화
| name | security |
| description | 보안 취약점 분석, OWASP Top 10, 인증/인가 패턴 |
# Bad: 권한 검증 없음
function getUser(userId):
return db.users.findById(userId)
# Good: 권한 검증
function getUser(userId, requestingUser):
if requestingUser.id != userId and not requestingUser.isAdmin:
throw ForbiddenError("Access denied")
return db.users.findById(userId)
# Bad: 평문 저장
user.password = inputPassword
# Good: 해시 저장
user.passwordHash = bcrypt.hash(inputPassword, saltRounds=12)
# Bad: 약한 암호화
encrypted = base64.encode(sensitiveData)
# Good: 강력한 암호화
encrypted = AES256.encrypt(sensitiveData, secretKey)
# Bad: SQL Injection 취약
query = "SELECT * FROM users WHERE id = " + userId
# Good: Parameterized Query
query = "SELECT * FROM users WHERE id = ?"
db.execute(query, [userId])
# Bad: XSS 취약
html = "<div>" + userInput + "</div>"
# Good: 이스케이프 처리
html = "<div>" + escapeHtml(userInput) + "</div>"
# Bad: 비밀번호 힌트
function recoverPassword(email, hint):
if user.passwordHint == hint:
return user.password # 절대 금지!
# Good: 토큰 기반 복구
function recoverPassword(email):
token = generateSecureToken()
sendRecoveryEmail(email, token)
storeTokenWithExpiry(token, 1hour)
# Bad: 디버그 모드 프로덕션 배포
DEBUG = true
SHOW_ERRORS = true
# Good: 환경별 설정
DEBUG = environment == "development"
SHOW_ERRORS = false # 프로덕션에서는 로깅만
# Bad: 기본 비밀번호
ADMIN_PASSWORD = "admin123"
# Good: 환경 변수
ADMIN_PASSWORD = env.get("ADMIN_PASSWORD")
# Bad: 약한 시크릿
secret = "mysecret"
# Good: 강력한 시크릿
secret = env.get("JWT_SECRET") # 최소 256비트
# Bad: 토큰에 민감정보
payload = {userId, email, password, ssn}
# Good: 최소 정보만
payload = {userId, role, exp}
# 토큰 검증
function verifyToken(token):
try:
decoded = jwt.verify(token, secret, algorithms=["HS256"])
if decoded.exp < now():
throw TokenExpiredError()
return decoded
catch:
throw InvalidTokenError()
# 세션 설정 권장사항
session.config = {
httpOnly: true, # JavaScript 접근 차단
secure: true, # HTTPS만 허용
sameSite: "strict", # CSRF 방지
maxAge: 3600, # 1시간 만료
}
# 로그아웃 시 세션 무효화
function logout(sessionId):
session.destroy(sessionId)
blacklist.add(sessionId)
# 역할 정의
ROLES = {
admin: ["read", "write", "delete", "admin"],
editor: ["read", "write"],
viewer: ["read"],
}
# 권한 검증 미들웨어
function requirePermission(permission):
return function(request, next):
userRole = request.user.role
if permission not in ROLES[userRole]:
throw ForbiddenError()
next()
# 사용
@requirePermission("write")
function updatePost(postId, content):
...
# Bad: ID만 검증
function deletePost(postId):
db.posts.delete(postId)
# Good: 소유권 검증
function deletePost(postId, userId):
post = db.posts.findById(postId)
if post.authorId != userId and not user.isAdmin:
throw ForbiddenError("Not authorized")
db.posts.delete(postId)
# Bad: 블랙리스트
if "<script>" not in input:
process(input)
# Good: 화이트리스트
ALLOWED_TAGS = ["p", "b", "i", "a"]
sanitized = sanitizeHtml(input, allowedTags=ALLOWED_TAGS)
# 타입 검증
function validateUser(data):
schema = {
email: {type: "email", required: true},
age: {type: "integer", min: 0, max: 150},
name: {type: "string", maxLength: 100},
}
return validate(data, schema)
# Bad: 확장자만 검증
if filename.endswith(".jpg"):
save(file)
# Good: MIME 타입 + 확장자 + 크기 검증
ALLOWED_TYPES = ["image/jpeg", "image/png"]
MAX_SIZE = 5 * 1024 * 1024 # 5MB
function validateUpload(file):
if file.mimetype not in ALLOWED_TYPES:
throw InvalidFileError()
if file.size > MAX_SIZE:
throw FileTooLargeError()
# 파일 내용 검증 (매직 넘버)
if not isValidImage(file.buffer):
throw InvalidFileError()
api-design: API 보안 설계code-quality: 안전한 에러 처리