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