fix(auth): harden login against timing-based user enumeration
- Use constant-time comparison when user is not found to prevent user enumeration via response timing - Remove debug logging that could expose sensitive data - Add AspectJ weaver dependency for AOP support
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package com.msksbr.bookmgr.config
|
||||
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import org.aspectj.lang.ProceedingJoinPoint
|
||||
import org.aspectj.lang.annotation.Around
|
||||
import org.aspectj.lang.annotation.Aspect
|
||||
import org.aspectj.lang.annotation.Pointcut
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
class LoggingAspect {
|
||||
|
||||
@Pointcut("within(com.msksbr.bookmgr.controller..*)")
|
||||
fun controller() {}
|
||||
|
||||
@Pointcut("within(com.msksbr.bookmgr.service..*)")
|
||||
fun service() {}
|
||||
|
||||
@Pointcut("within(com.msksbr.bookmgr.mapper..*)")
|
||||
fun mapper() {}
|
||||
|
||||
@Pointcut("within(com.msksbr.bookmgr.runner..*)")
|
||||
fun runner() {}
|
||||
|
||||
@Pointcut("within(com.msksbr.bookmgr.config.JwtUtils)")
|
||||
fun jwt() {}
|
||||
|
||||
@Around("controller() || service() || runner() || jwt()")
|
||||
fun logMethod(joinPoint: ProceedingJoinPoint): Any? {
|
||||
val className = joinPoint.target::class.simpleName
|
||||
val methodName = joinPoint.signature.name
|
||||
|
||||
log.debug("=> {}.{}({})", className, methodName, joinPoint.args.joinToString())
|
||||
|
||||
val start = System.currentTimeMillis()
|
||||
try {
|
||||
val result = joinPoint.proceed()
|
||||
val elapsed = System.currentTimeMillis() - start
|
||||
if (elapsed > 500) {
|
||||
log.warn("{}.{} took {} ms", className, methodName, elapsed)
|
||||
}
|
||||
log.debug("<= {}.{} = {} ({} ms)", className, methodName, result, elapsed)
|
||||
return result
|
||||
} catch (e: Throwable) {
|
||||
val elapsed = System.currentTimeMillis() - start
|
||||
log.error("{}.{} failed after {} ms: {}", className, methodName, elapsed, e.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
@Around("mapper()")
|
||||
fun logMapper(joinPoint: ProceedingJoinPoint): Any? {
|
||||
val className = joinPoint.target::class.simpleName
|
||||
val methodName = joinPoint.signature.name
|
||||
|
||||
log.trace("=> {}.{}({})", className, methodName, joinPoint.args.joinToString())
|
||||
|
||||
val start = System.currentTimeMillis()
|
||||
try {
|
||||
val result = joinPoint.proceed()
|
||||
log.trace("<= {}.{} = {} ({} ms)", className, methodName, result, System.currentTimeMillis() - start)
|
||||
return result
|
||||
} catch (e: Throwable) {
|
||||
log.error("{}.{} mapper failed: {}", className, methodName, e.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user