➕ New issues 567
✅ Resolved issues 0
No resolved issues
Number of issues per severity level (CRITICAL, HIGH, MEDIUM, LOW, INFO)
Number of issues per audit category (Security, Architecture, UI, UX, Maintenance) — not to be confused with severity above
HIGH / MEDIUM / LOW over 10 audits
v1.0.0
fc393c9d-2305-4f26-8b89-8be52f3f4d00
~/JeecgBoot
html, java, javascript, yaml
javascript: .js, .jsx, .ts, .tsx, .mjshtml: .html, .htm, .xhtml, .shtml, .vue, .svelte, .ejs, .hbs, .njk, .jinja, .jinja2, .twig, .liquid, .mustache, .phtml, .erb, .jsp, .asp, .aspx, .cshtml
. jeecg-boot-base-core/ jeecg-module-demo/ jeecg-module-system/ jeecg-server-cloud/
**/node_modules/** **/__pycache__/** **/.venv/** **/venv/** **/vendor/** **/.git/** **/dist/** **/build/** **/src/main/resources/static/** **/bower_components/** **/*.min.js audit-reports/ audit-datas/
Ranked by severity score (CRITICAL×10, HIGH×5, MEDIUM×2, LOW×1)
No resolved issues
The most frequent issue in each category, with a real instance detected in this project and the generic fix for this type of pattern.
log.error(e.getMessage(),e);💡 This rule flags a broader principle than just this snippet: Use a logging framework (SLF4J/Log4j2) with appropriate log levels. Never expose stack traces to users.. The example below illustrates the general fix principle, not necessarily your exact case.
logger.error("Error", e);
return Internal server error ;for (Field field : fields) {💡 This rule flags a broader principle than just this snippet: Use batch fetching, JOIN FETCH, or @EntityGraph to load related entities in a single query.. The example below illustrates the general fix principle, not necessarily your exact case.
@EntityGraph(attributePaths = items )
List<Order> findAll(); // 1 query with JOIN} catch (Exception e) {💡 This rule flags a broader principle than just this snippet: Catch specific exception types. Use multi-catch if needed (catch (IOException | SQLException e)).. The example below illustrates the general fix principle, not necessarily your exact case.
catch (IOException e) { logger.error("IO error", e); }✅ No issues detected in this category.
Container runs as root user by default, increasing blast radius if compromised (CWE-250).
Add a USER directive with a non-root user (e.g., USER appuser) after installing dependencies.
💡 Principle of least privilege, reduced container escape risk.
FROM node:20-alpine
RUN npm install
CMD ["node", app.js ]FROM node:20-alpine
RUN npm install
USER node
CMD ["node", app.js ]Logging passwords, tokens, or API keys exposes secrets in log files and monitoring systems.
Never log sensitive data. Use placeholder values or mask secrets before logging.
logger.info("Token: " + apiKey);logger.info("Token: [REDACTED]");String token = request.getHeader(TOKEN_KEY);String token = request.getHeader(TOKEN_KEY);log.debug("Websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token);log.debug("Websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token);String token = request.getHeader(TOKEN_KEY);String token = request.getHeader(TOKEN_KEY);//log.error("Websocket连接 Token安全校验失败,IP:{}, Token:{}, Path = {},异常:{}", oConvertUtils.getIpAddrByRequest(request), token, request.getRequestURI(), exception.getMessage());//log.error("Websocket连接 Token安全校验失败,IP:{}, Token:{}, Path = {},异常:{}", oConvertUtils.getIpAddrByRequest(request), token, request.getRequestURI(), exception.getMessage());String token = request.getHeader(TOKEN_KEY);String token = request.getHeader(TOKEN_KEY);log.debug("Websocket连接 Token安全校验失败,IP:{}, Token:{}, Path = {},异常:{}", oConvertUtils.getIpAddrByRequest(request), token, request.getRequestURI(), exception.getMessage());log.debug("Websocket连接 Token安全校验失败,IP:{}, Token:{}, Path = {},异常:{}", oConvertUtils.getIpAddrByRequest(request), token, request.getRequestURI(), exception.getMessage());CasClientController.validateLogin(ticket)CasClientController.validateLogin(ticket)log.info("-------token----username---"+principal);log.info("-------token----username---"+principal);Storing a sensitive value (password, token, secret) as a plaintext String field in a class allows it to persist in JVM memory, heap dumps, thread dumps, and serialized objects — once stored in a String, the value cannot be zeroed from memory and may linger in the JVM string pool (CWE-499, CWE-312).
Use char[] instead of String for sensitive data — char arrays can be zeroed after use (Arrays.fill(password, \0 )). Better yet, use a SecretKey object (javax.crypto.SecretKey) or avoid storing credentials in memory longer than necessary.
private String password;private char[] password;
// After use:
// Arrays.fill(password, \0 );SQL query executed in a file containing HTTP request parameters — potential SQL injection (CWE-89).
Use parameterized queries with PreparedStatement and bound parameters.
stmt.executeQuery("SELECT * FROM users WHERE id=" + id);PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id=?");
ps.setInt(1, id);public Result<Object> resumeJob(@RequestParam(name = "id") String id) {public Result<Object> resumeJob(@RequestParam(name = "id") String id) {quartzJobService.execute(quartzJob);quartzJobService.execute(quartzJob);Spring MultipartFile.transferTo() or getOriginalFilename() without file type validation allows uploading of web shells, malware, and executable files (CWE-434, OWASP A04).
Validate file type via magic bytes (Apache Tika or Files.probeContentType), enforce a strict allowlist of extensions, and store files outside the web root with randomized names.
public String upload(@RequestParam MultipartFile file) {
file.transferTo(new File(UPLOAD_DIR + file.getOriginalFilename()));
return ok ;
}private static final Set<String> ALLOWED = Set.of(".jpg", .png , .pdf );
public String upload(@RequestParam MultipartFile file) {
String ext = FilenameUtils.getExtension(file.getOriginalFilename()).toLowerCase();
if (!ALLOWED.contains("." + ext)) throw new IllegalArgumentException("Type non autorisé");
String safe = UUID.randomUUID() + . + ext;
file.transferTo(new File(UPLOAD_DIR + safe));
return ok ;
}Use SHA-256 or SHA-3 (MessageDigest.getInstance("SHA-256")). For passwords, use BCrypt/Argon2.
Cipher.getInstance("DES");Cipher.getInstance("AES/GCM/NoPadding");System command executed in a file containing HTTP request parameters — potential command injection (CWE-78).
Avoid passing user input to system commands. Use parameterized APIs instead of shell execution.
Runtime.getRuntime().exec("cmd " + userInput);ProcessBuilder pb = new ProcessBuilder("cmd", validatedArg);
pb.start();public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,return xxlJobService.start(id);return xxlJobService.start(id);ObjectInputStream.readObject() without validation allows arbitrary code running.
Use ObjectInputFilter (Java 9+) or a whitelist of allowed classes. Prefer JSON/XML serialization.
💡 Protection against deserialization attacks (OWASP A08, CWE-502).
ObjectInputStream ois = new ObjectInputStream(stream);
Object obj = ois.readObject();// Use JSON or validated deserialization
Object obj = objectMapper.readValue(json, SafeType.class);Runtime.getRuntime() with user input allows arbitrary OS command running.
Use ProcessBuilder with argument list (no shell interpretation). Validate and whitelist inputs.
Runtime.getRuntime().exec("cmd " + userInput);ProcessBuilder pb = new ProcessBuilder("cmd", validatedArg);
pb.start();DocumentBuilderFactory without setFeature allows XML External Entity attacks (file read, SSRF).
Disable DTDs and external entities: factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true).
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.newDocumentBuilder().parse(input);DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.newDocumentBuilder().parse(input);${} in MyBatis annotations performs string interpolation (not parameterization), enabling SQL injection.
Use
💡 Prevention of SQL injection in MyBatis queries (OWASP A03, CWE-89).
stmt.executeQuery("SELECT * FROM users WHERE id=" + id);PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id=?");
ps.setInt(1, id);FileInputStream with user-controlled path allows directory traversal to read arbitrary files (CWE-22).
Validate and canonicalize file paths. Use Path.normalize().startsWith(basePath) to restrict access.
new FileInputStream(request.getParameter("file"));Path safe = Path.of(base, name).normalize();
if (safe.startsWith(base)) new FileInputStream(safe.toFile());An attacker can inject CRLF sequences (\r\n) into HTTP headers to split the response, inject additional headers, perform cache poisoning, or conduct cross-site scripting attacks.
Strip CRLF characters (\r, \n) from user input before setting any HTTP response header.
response.headers['Location'] = request.args.get('url')url = request.args.get('url').replace('\r', ).replace('\n', )
response.headers['Location'] = urlString token = request.getHeader(TOKEN_KEY);String token = request.getHeader(TOKEN_KEY);response.setHeader(TOKEN_KEY, token);response.setHeader(TOKEN_KEY, token);An attacker can read or write arbitrary files outside the intended directory.
Validate file paths with os.path.realpath() and ensure they stay within the allowed directory.
filename = request.args.get("file")
content = open(os.path.join(BASE, filename)).read()filename = request.args.get("file")
safe = os.path.realpath(os.path.join(BASE, filename))
if not safe.startswith(os.path.realpath(BASE)):
abort(403)
content = open(safe).read()String orgName = mf.getOriginalFilename();String orgName = mf.getOriginalFilename();File savefile = new File(savePath);File savefile = new File(savePath);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");File file = new File(ctxPath + File.separator + bizPath + File.separator );File file = new File(ctxPath + File.separator + bizPath + File.separator );String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");File savefile = new File(savePath);File savefile = new File(savePath);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");// File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);// File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");// File savefile = new File(savePath);// File savefile = new File(savePath);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");File file = new File(filePath);File file = new File(filePath);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");this.uploadLocal(...) → File file = new File(ctxPath + File.separator + bizPath + File.separator );File file = new File(ctxPath + File.separator + bizPath + File.separator );savePath = this.uploadLocal(file,bizPath);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");File file = new File(ctxPath + File.separator + bizPath + File.separator);File file = new File(ctxPath + File.separator + bizPath + File.separator);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");File savefile = new File(savePath);File savefile = new File(savePath);String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");this.uploadLocal(...) → File file = new File(ctxPath + File.separator + bizPath + File.separator);File file = new File(ctxPath + File.separator + bizPath + File.separator);savePath = this.uploadLocal(file, bizPath);An attacker can read, modify, or delete database records.
Use parameterized queries with placeholders (%s, ?).
user_id = request.args.get("id")
db.execute(f"SELECT * FROM users WHERE id = {user_id}")user_id = request.args.get("id")
db.execute("SELECT * FROM users WHERE id = %s", (user_id,))public ReturnT<String> save(Model model, int id, String glueSource, String glueRemark) {public ReturnT<String> save(Model model, int id, String glueSource, String glueRemark) {xxlJobInfoDao.update(exists_jobInfo);xxlJobInfoDao.update(exists_jobInfo);An attacker can inject malicious scripts that execute in other users' browsers.
Escape all user input before rendering in HTML. Use framework auto-escaping or html.escape().
name = request.args.get("name")
return Markup(f"<h1>Hello {name}</h1>")from markupsafe import escape
name = request.args.get("name")
return Markup(f"<h1>Hello {escape(name)}</h1>")String bizPath = request.getParameter("biz");String bizPath = request.getParameter("biz");// String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());// String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());An attacker can redirect users to a malicious site via a crafted URL.
Validate redirect targets against an allowlist. Use url_for() for internal redirects.
next_url = request.args.get("next")
return redirect(next_url)next_url = request.args.get("next", / )
if not is_safe_url(next_url, request.host):
next_url = /
return redirect(next_url)public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {response.sendRedirect(authorizeUrl);response.sendRedirect(authorizeUrl);public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {response.sendRedirect(url);response.sendRedirect(url);public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {response.sendRedirect(state);response.sendRedirect(state);No issues in dependencies.
printStackTrace() exposes internal stack traces, class names, and paths to attackers.
Use a logging framework (SLF4J/Log4j2) with appropriate log levels. Never expose stack traces to users.
💡 Prevention of information disclosure (OWASP A09, CWE-209).
return e.getStackTrace().toString();logger.error("Error", e);
return Internal server error ;JobLogController.logKill(id)JobLogController.logKill(id)logger.error(e.getMessage(), e);logger.error(e.getMessage(), e);MultipartFile file = entity.getValue();MultipartFile file = entity.getValue();log.error(e.getMessage(),e);log.error(e.getMessage(),e);Comparing an int loop variable against a long or wider value (e.g., array.length cast to long) in a loop condition loses precision — if the long value exceeds Integer.MAX_VALUE, the int variable never reaches it, creating an infinite loop or off-by-one error exploitable for denial of service (CWE-190, CWE-197).
Ensure both sides of the loop comparison have compatible types. Cast the wider type to int after validating it fits, or use a long loop variable if the range may exceed int bounds.
for (int i = 0; i < data.length; i++) { process(data[i]); }if (data.length > Integer.MAX_VALUE) throw new IllegalArgumentException("Too large");
for (int i = 0; i < (int) data.length; i++) { process(data[i]); }Checking file existence or permissions before operating on the file introduces a TOCTOU (time-of-check time-of-use) race condition — an attacker with write access to the directory can replace the file with a symlink between the check and the operation, causing the application to operate on an unintended file (CWE-367).
Use atomic file operations. Open the file directly and handle the FileNotFoundException/NoSuchFileException rather than pre-checking existence. Use Files.createFile() with StandardOpenOption.CREATE_NEW for atomic creation.
if (file.exists()) {
processFile(file);
}try {
processFile(file);
} catch (NoSuchFileException e) {
// file did not exist
}java.util.Random is not cryptographically secure. Predictable values enable session hijacking or token forgery (CWE-330).
Use java.security.SecureRandom for security-sensitive operations.
int token = new Random().nextInt();int token = SecureRandom.getInstanceStrong().nextInt();java.util.Random is predictable — tokens, sessions, and keys generated with it can be guessed.
Use java.security.SecureRandom for all security-sensitive random generation.
int token = new Random().nextInt();int token = SecureRandom.getInstanceStrong().nextInt();Cookies without HttpOnly are accessible via JavaScript (XSS). Without Secure, they are sent over unencrypted HTTP (CWE-614, OWASP A05).
Always set HttpOnly=True and Secure=True on session and authentication cookies.
💡 Cookies protected against XSS theft and network interception.
response.set_cookie("session_id", token)response.set_cookie(
session_id , token,
httponly=True, secure=True, samesite="Lax"
)An attacker can forge log entries, hide traces, or exploit log processing tools.
Sanitize user input before logging by removing newlines and control characters.
user_agent = request.headers.get("User-Agent")
logger.info(f"Request from: {user_agent}")user_agent = request.headers.get("User-Agent", )
safe_ua = user_agent.replace("\n", ).replace("\r", )
logger.info("Request from: %s", safe_ua)String val = t.getValue().replace(EXCEL_SPLIT_TAG,TEMP_EXCEL_SPLIT_TAG);String val = t.getValue().replace(EXCEL_SPLIT_TAG,TEMP_EXCEL_SPLIT_TAG);log.info("---AutoPoi--Get_DB_Dict------"+ dictReplaces.toString());log.info("---AutoPoi--Get_DB_Dict------"+ dictReplaces.toString());String requestURI = request.getRequestURI();String requestURI = request.getRequestURI();log.info("经过多数据源Interceptor,当前路径是{}", requestURI);log.info("经过多数据源Interceptor,当前路径是{}", requestURI);log.info("Sign Interceptor request URI = " + request.getRequestURI());log.info("Sign Interceptor request URI = " + request.getRequestURI());log.info("Sign Interceptor request URI = " + request.getRequestURI());log.info("Sign Interceptor request URI = " + request.getRequestURI());String headerSign = request.getHeader(CommonConstant.X_SIGN);String headerSign = request.getHeader(CommonConstant.X_SIGN);log.debug("Sign 签名通过!Header Sign : {}",headerSign);log.debug("Sign 签名通过!Header Sign : {}",headerSign);log.error("request URI = " + request.getRequestURI());log.error("request URI = " + request.getRequestURI());log.error("request URI = " + request.getRequestURI());log.error("request URI = " + request.getRequestURI());String headerSign = request.getHeader(CommonConstant.X_SIGN);String headerSign = request.getHeader(CommonConstant.X_SIGN);log.error("Sign 签名校验失败!Header Sign : {}",headerSign);log.error("Sign 签名校验失败!Header Sign : {}",headerSign);String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);log.info(" pathVariable: {}",pathVariable);log.info(" pathVariable: {}",pathVariable);String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);log.info(" pathVariable decode: {}",deString);log.info(" pathVariable decode: {}",deString);String accessToken = request.getHeader("X-Access-Token");String accessToken = request.getHeader("X-Access-Token");log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);getDomain()getDomain()log.info(" RestUtil.getBaseUrl: " + basepath);log.info(" RestUtil.getBaseUrl: " + basepath);log.debug(" -- url --" + request.getRequestURL());log.debug(" -- url --" + request.getRequestURL());log.debug(" -- url --" + request.getRequestURL());log.debug(" -- url --" + request.getRequestURL());String xGatewayBasePath = request.getHeader(ServiceNameConstants.X_GATEWAY_BASE_PATH);String xGatewayBasePath = request.getHeader(ServiceNameConstants.X_GATEWAY_BASE_PATH);log.info("x_gateway_base_path = "+ xGatewayBasePath);log.info("x_gateway_base_path = "+ xGatewayBasePath);String scheme = request.getHeader(CommonConstant.X_FORWARDED_SCHEME);String scheme = request.getHeader(CommonConstant.X_FORWARDED_SCHEME);log.debug("-----Common getBaseUrl----- : " + baseDomainPath);log.debug("-----Common getBaseUrl----- : " + baseDomainPath);String orgName = file.getOriginalFilename();String orgName = file.getOriginalFilename();log.info("------OSS文件上传成功------" + fileUrl);log.info("------OSS文件上传成功------" + fileUrl);MultipartFile file = entity.getValue();MultipartFile file = entity.getValue();log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");String requestPath = request.getRequestURI().substring(request.getContextPath().length());String requestPath = request.getRequestURI().substring(request.getContextPath().length());log.info("拦截请求 >> {} ; 请求类型 >> {} . ", requestPath, requestMethod);log.info("拦截请求 >> {} ; 请求类型 >> {} . ", requestPath, requestMethod);public String getMessage(@RequestParam String name) {public String getMessage(@RequestParam String name) {log.info(" 微服务被调用:{} ",msg);log.info(" 微服务被调用:{} ",msg);public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,log.info("查询当前页:" + pageList.getCurrent());log.info("查询当前页:" + pageList.getCurrent());public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,log.info("查询当前页数量:" + pageList.getSize());log.info("查询当前页数量:" + pageList.getSize());public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,log.info("查询结果数量:" + pageList.getRecords().size());log.info("查询结果数量:" + pageList.getRecords().size());public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,log.info("数据总数:" + pageList.getTotal());log.info("数据总数:" + pageList.getTotal());public JeecgDemo redisGetJeecgDemo(@PathVariable("id") String id) {public JeecgDemo redisGetJeecgDemo(@PathVariable("id") String id) {log.info(t.toString());log.info(t.toString());public Result<?> testOnlineAdd(@RequestBody JSONObject json) {public Result<?> testOnlineAdd(@RequestBody JSONObject json) {log.info(json.toJSONString());log.info(json.toJSONString());public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info(" =========================================================== ");log.info(" =========================================================== ");public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info("params: " + params.toJSONString());log.info("params: " + params.toJSONString());public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info("params.tableName: " + params.getString("tableName"));log.info("params.tableName: " + params.getString("tableName"));public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info("params.json: " + params.getJSONObject("json").toJSONString());log.info("params.json: " + params.getJSONObject("json").toJSONString());public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info("params.dataList: " + dataList.toJSONString());log.info("params.dataList: " + dataList.toJSONString());public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info(" =========================================================== ");log.info(" =========================================================== ");public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info(" =========================================================== ");log.info(" =========================================================== ");public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info("params: " + params.toJSONString());log.info("params: " + params.toJSONString());public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info("params.tableName: " + params.getString("tableName"));log.info("params.tableName: " + params.getString("tableName"));public Result enhanceJavaListHttp(@RequestBody JSONObject params) {public Result enhanceJavaListHttp(@RequestBody JSONObject params) {log.info("params.json: " + params.getJSONObject("json").toJSONString());log.info("params.json: " + params.getJSONObject("json").toJSONString());public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {log.info(" --- params:" + params.toJSONString());log.info(" --- params:" + params.toJSONString());public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {log.info(" --- params:" + params.toJSONString());log.info(" --- params:" + params.toJSONString());public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {log.info(" --- tableName:" + tableName);log.info(" --- tableName:" + tableName);public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {log.info(" --- 行数据:" + record.toJSONString());log.info(" --- 行数据:" + record.toJSONString());log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);replaceValue()replaceValue()addEasyQuery(...) → log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);addEasyQuery(queryWrapper, column, rule, value);public Result getMockDdjhData(public Result getMockDdjhData(log.error("-- 高级查询操作失败:" + superQueryParams, e);log.error("-- 高级查询操作失败:" + superQueryParams, e);public Result getMockDdjhData(public Result getMockDdjhData(log.error("-- 高级查询操作失败:" + superQueryParams, e);log.error("-- 高级查询操作失败:" + superQueryParams, e);public Result<DegradeRuleEntity> apiAddRule(@RequestBody DegradeRuleEntity entity) {public Result<DegradeRuleEntity> apiAddRule(@RequestBody DegradeRuleEntity entity) {logger.error("Failed to add new degrade rule, app={}, ip={}", entity.getApp(), entity.getIp(), t);logger.error("Failed to add new degrade rule, app={}, ip={}", entity.getApp(), entity.getIp(), t);public Result<DegradeRuleEntity> apiUpdateRule(@PathVariable("id") Long id,public Result<DegradeRuleEntity> apiUpdateRule(@PathVariable("id") Long id,logger.error("Failed to save degrade rule, id={}, rule={}", id, entity, t);logger.error("Failed to save degrade rule, id={}, rule={}", id, entity, t);public Result<Long> delete(@PathVariable("id") Long id) {public Result<Long> delete(@PathVariable("id") Long id) {logger.error("Failed to delete degrade rule, id={}", id, throwable);logger.error("Failed to delete degrade rule, id={}", id, throwable);public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,logger.error("Error when updating parameter flow rules, id=" + id, ex.getCause());logger.error("Error when updating parameter flow rules, id=" + id, ex.getCause());public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,logger.error("Error when updating parameter flow rules, id=" + id, throwable);logger.error("Error when updating parameter flow rules, id=" + id, throwable);// log.debug("Feign request: {}", request.getRequestURI());// log.debug("Feign request: {}", request.getRequestURI());// log.debug("Feign request: {}", request.getRequestURI());// log.debug("Feign request: {}", request.getRequestURI());public Object validateLogin(@RequestParam(name="ticket") String ticket,public Object validateLogin(@RequestParam(name="ticket") String ticket,log.info("Rest api login.");log.info("Rest api login.");public Object validateLogin(@RequestParam(name="ticket") String ticket,public Object validateLogin(@RequestParam(name="ticket") String ticket,log.info("res."+res);log.info("res."+res);map.put("used_memory", entry.getValue());map.put("used_memory", entry.getValue());log.debuglog.debug("--getMemoryInfo--: " + map.toString());public void onOpen(Session session, @PathParam(value = "userId") String userId) {public void onOpen(Session session, @PathParam(value = "userId") String userId) {log.info("【系统 WebSocket】有新的连接,总数为:" + sessionPool.size());log.info("【系统 WebSocket】有新的连接,总数为:" + sessionPool.size());public void onOpen(Session session, @PathParam(value = "userId") String userId) {public void onOpen(Session session, @PathParam(value = "userId") String userId) {log.info("【系统 WebSocket】连接断开,总数为:" + sessionPool.size());log.info("【系统 WebSocket】连接断开,总数为:" + sessionPool.size());Session session = item.getValue();Session session = item.getValue();log.info("【系统 WebSocket】推送单人消息:" + message);log.info("【系统 WebSocket】推送单人消息:" + message);public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {log.info("保存数据规则>>"+"菜单ID:"+permissionId+"部门ID:"+ departId+"数据权限ID:"+dataRuleIds);log.info("保存数据规则>>"+"菜单ID:"+permissionId+"部门ID:"+ departId+"数据权限ID:"+dataRuleIds);public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("查询当前页:"+pageList.getCurrent());log.info("查询当前页:"+pageList.getCurrent());public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("查询当前页数量:"+pageList.getSize());log.info("查询当前页数量:"+pageList.getSize());public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("查询结果数量:"+pageList.getRecords().size());log.info("查询结果数量:"+pageList.getRecords().size());public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("数据总数:"+pageList.getTotal());log.info("数据总数:"+pageList.getTotal());public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,//log.info("查询当前页:"+pageList.getCurrent());//log.info("查询当前页:"+pageList.getCurrent());public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,//log.info("查询当前页数量:"+pageList.getSize());//log.info("查询当前页数量:"+pageList.getSize());public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,//log.info("查询结果数量:"+pageList.getRecords().size());//log.info("查询结果数量:"+pageList.getRecords().size());public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,public Result<IPage<SysAnnouncementSend>> queryPageList(SysAnnouncementSend sysAnnouncementSend,//log.info("数据总数:"+pageList.getTotal());//log.info("数据总数:"+pageList.getTotal());public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.debug("查询当前页:"+pageList.getCurrent());log.debug("查询当前页:"+pageList.getCurrent());public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.debug("查询当前页数量:"+pageList.getSize());log.debug("查询当前页数量:"+pageList.getSize());public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.debug("查询结果数量:"+pageList.getRecords().size());log.debug("查询结果数量:"+pageList.getRecords().size());public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.debug("数据总数:"+pageList.getTotal());log.debug("数据总数:"+pageList.getTotal());public Result<String> getDictText(@PathVariable("dictCode") String dictCode, @PathVariable("key") String key) {public Result<String> getDictText(@PathVariable("dictCode") String dictCode, @PathVariable("key") String key) {log.info(" dictCode : "+ dictCode);log.info(" dictCode : "+ dictCode);public Result<List<DictModel>> getDictItems(@PathVariable("dictCode") String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {public Result<List<DictModel>> getDictItems(@PathVariable("dictCode") String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {log.info(" dictCode : "+ dictCode);log.info(" dictCode : "+ dictCode);public Result<List<DictModel>> loadDict(@PathVariable("dictCode") String dictCode,public Result<List<DictModel>> loadDict(@PathVariable("dictCode") String dictCode,log.info(" 加载字典表数据,加载关键字: "+ keyword);log.info(" 加载字典表数据,加载关键字: "+ keyword);SysDictController.loadDictOrderByValue(keyword)SysDictController.loadDictOrderByValue(keyword)this.loadDict(...) → log.info(" 加载字典表数据,加载关键字: "+ keyword);log.info(" 加载字典表数据,加载关键字: "+ keyword);Result<List<DictModel>> firstRes = this.loadDict(dictCode, keyword, sign, null);SysDictController.loadTreeData(tbname)SysDictController.loadTreeData(tbname)SqlInjectionUtil.filterContent(...) → log.error("请注意,值可能存在SQL注入风险!---> {}", value);log.error("请注意,值可能存在SQL注入风险!---> {}", value);SqlInjectionUtil.filterContent(dictCode);MultipartFile file = entity.getValue();MultipartFile file = entity.getValue();log.info("排序后的list====>",listSysCategorys);log.info("排序后的list====>",listSysCategorys);MultipartFile file = entity.getValue();MultipartFile file = entity.getValue();log.info("pCode====>",pCode);log.info("pCode====>",pCode);MultipartFile file = entity.getValue();MultipartFile file = entity.getValue();log.info("pId====>",pId);log.info("pId====>",pId);public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {log.info("保存数据规则>>"+"菜单ID:"+permissionId+"角色ID:"+ roleId+"数据权限ID:"+dataRuleIds);log.info("保存数据规则>>"+"菜单ID:"+permissionId+"角色ID:"+ roleId+"数据权限ID:"+dataRuleIds);public Result<Object> forceLogout(@RequestBody SysUserOnlineVO online) {public Result<Object> forceLogout(@RequestBody SysUserOnlineVO online) {log.info(" 强制 "+sysUser.getRealname()+"退出成功! ");log.info(" 强制 "+sysUser.getRealname()+"退出成功! ");public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("查询当前页:"+pageList.getCurrent());log.info("查询当前页:"+pageList.getCurrent());public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("查询当前页数量:"+pageList.getSize());log.info("查询当前页数量:"+pageList.getSize());public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("查询结果数量:"+pageList.getRecords().size());log.info("查询结果数量:"+pageList.getRecords().size());public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,public Result<IPage<SysLog>> queryPageList(SysLog syslog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,log.info("数据总数:"+pageList.getTotal());log.info("数据总数:"+pageList.getTotal());public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {log.info("第三方登录进入render:" + source);log.info("第三方登录进入render:" + source);public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {log.info("第三方登录认证地址:" + authorizeUrl);log.info("第三方登录认证地址:" + authorizeUrl);public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {log.info("第三方登录进入callback:" + source + " params:" + JSONObject.toJSONString(callback));log.info("第三方登录进入callback:" + source + " params:" + JSONObject.toJSONString(callback));public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {public String loginThird(@PathVariable("source") String source, AuthCallback callback,ModelMap modelMap) {log.info(JSONObject.toJSONString(response));log.info(JSONObject.toJSONString(response));public Result<String> thirdUserCreate(@RequestBody ThirdLoginModel model) {public Result<String> thirdUserCreate(@RequestBody ThirdLoginModel model) {log.info("第三方登录创建新账号:" );log.info("第三方登录创建新账号:" );public String oauth2LoginCallback(@PathVariable("source") String source, @RequestParam("state") String state, HttpServletRequest request, HttpServletResponse response) throws Exception {public String oauth2LoginCallback(@PathVariable("source") String source, @RequestParam("state") String state, HttpServletRequest request, HttpServletResponse response) throws Exception {log.info("oauth2 login url:" + url);log.info("oauth2 login url:" + url);public String oauth2LoginCallback(public String oauth2LoginCallback(log.info("【企业微信】OAuth2登录进入callback:code=" + code + ", state=" + state);log.info("【企业微信】OAuth2登录进入callback:code=" + code + ", state=" + state);public String oauth2LoginCallback(public String oauth2LoginCallback(log.info("【钉钉】OAuth2登录进入callback:authCode=" + authCode + ", state=" + state);log.info("【钉钉】OAuth2登录进入callback:authCode=" + authCode + ", state=" + state);public String oauth2LoginCallback(public String oauth2LoginCallback(log.info("OAuth2登录重定向地址: " + state);log.info("OAuth2登录重定向地址: " + state);public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) {public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) {log.info("listByUser接口新增了SysAnnouncementSend:pageSize{}:"+pageSize);log.info("listByUser接口新增了SysAnnouncementSend:pageSize{}:"+pageSize);public Result<Boolean> checkUsername(String id,String roleCode) {public Result<Boolean> checkUsername(String id,String roleCode) {log.info("--验证角色编码是否唯一---id:"+id+"--roleCode:"+roleCode);log.info("--验证角色编码是否唯一---id:"+id+"--roleCode:"+roleCode);public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {log.info("保存数据规则>>"+"菜单ID:"+permissionId+"角色ID:"+ roleId+"数据权限ID:"+dataRuleIds);log.info("保存数据规则>>"+"菜单ID:"+permissionId+"角色ID:"+ roleId+"数据权限ID:"+dataRuleIds);public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);log.info(" 用户名: "+sysUser.getRealname()+",退出成功! ");log.info(" 用户名: "+sysUser.getRealname()+",退出成功! ");public Result<String> sms(@RequestBody JSONObject jsonObject) {public Result<String> sms(@RequestBody JSONObject jsonObject) {log.info(mobile);log.info(mobile);public Result<String> randomImage(HttpServletResponse response,@PathVariable("key") String key){public Result<String> randomImage(HttpServletResponse response,@PathVariable("key") String key){log.info("获取验证码,Redis key = {},checkCode = {}", realKey, code);log.info("获取验证码,Redis key = {},checkCode = {}", realKey, code);public Result<?> getUserSectionInfoByToken(HttpServletRequest request, @RequestParam(name = "token", required = false) String token) {public Result<?> getUserSectionInfoByToken(HttpServletRequest request, @RequestParam(name = "token", required = false) String token) {log.debug(" ------ 通过令牌获取部分用户信息,当前用户: " + username);log.debug(" ------ 通过令牌获取部分用户信息,当前用户: " + username);public Result<?> getUserSectionInfoByToken(HttpServletRequest request, @RequestParam(name = "token", required = false) String token) {public Result<?> getUserSectionInfoByToken(HttpServletRequest request, @RequestParam(name = "token", required = false) String token) {log.debug(" ------ 通过令牌获取部分用户信息,已获取的用户信息: " + map);log.debug(" ------ 通过令牌获取部分用户信息,已获取的用户信息: " + map);SysUserController.queryUserComponentData(departId)SysUserController.queryUserComponentData(departId)SqlInjectionUtil.filterContent(...) → log.error("请注意,值可能存在SQL注入风险!---> {}", value);log.error("请注意,值可能存在SQL注入风险!---> {}", value);SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK);// public Object getDictItems(@PathVariable String dictCode) {// public Object getDictItems(@PathVariable String dictCode) {// log.info(" dictCode : "+ dictCode);// log.info(" dictCode : "+ dictCode);Database queries inside loops cause N+1 performance issues and heavy database load.
Use batch fetching, JOIN FETCH, or @EntityGraph to load related entities in a single query.
💡 Optimized database access, reduced query count and latency.
for (Order o : orders) {
o.getItems(); // lazy load = N queries
}@EntityGraph(attributePaths = items )
List<Order> findAll(); // 1 query with JOINA public non-constant field exposes the internal state of a class, breaking encapsulation. Any code can modify it directly, making invariants impossible to enforce and refactoring risky.
Make the field private and provide getter/setter methods. For immutable fields, use private final with a constructor or builder. For constants, use public static final.
public class User {
public String name;
public int age;
}public class User {
private String name;
private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}A repository.findAll() or getResultList() without pagination can return every row in the table. On large tables this causes out-of-memory errors, GC pressure, and request timeouts (CWE-770).
Use Spring Data Pageable: repository.findAll(PageRequest.of(page, size)). For JPA: query.setMaxResults(100).setFirstResult(offset). Never call findAll() or getResultList() without a limit in production code.
List<User> users = userRepository.findAll();Page<User> users = userRepository.findAll(PageRequest.of(page, PAGE_SIZE));catch(Exception e) swallows all exceptions including runtime errors, hiding bugs.
Catch specific exception types. Use multi-catch if needed (catch (IOException | SQLException e)).
💡 Precise error handling, no hidden failures (CWE-396).
catch (Exception e) { }catch (IOException e) { logger.error("IO error", e); }Code nested more than 5 levels deep is extremely difficult to read, test, and maintain. Deep nesting is a symptom of code that tries to do too much in a single block.
Apply early return / guard clauses to reduce nesting. Extract deeply nested logic into dedicated private methods.
for (User u : users) {
if (u.isActive()) {
for (Order o : u.getOrders()) {
if (o.isPending()) {
if (o.getAmount() > 0) {
if (stock.isAvailable(o)) {
process(o);
}
}
}
}
}
}private void processOrder(Order order) {
if (!order.isPending() || order.getAmount() <= 0) return;
if (!stock.isAvailable(order)) return;
process(order);
}A method or constructor with 6 or more parameters is a strong signal of a design problem. It is hard to call correctly, hard to test, and often violates the Single Responsibility Principle.
Group related parameters into a dedicated value object, record, or builder pattern. Alternatively, split the method into smaller, focused methods.
public User createUser(String name, String email, int age, String role, String address, String phone) {
return new User(name, email, age, role, address, phone);
}public User createUser(UserRequest request) {
return new User(request);
}No issues in dependencies.
A utility class (Utils, Helper, Constants) with a public constructor can be instantiated, which makes no semantic sense. Instantiating a utility class is a misuse of the API that can confuse developers.
Add a private constructor to prevent instantiation. Consider making the class final to prevent subclassing.
public class StringUtils {
public static String trim(String s) { return s.trim(); }
}public final class StringUtils {
private StringUtils() {
throw new UnsupportedOperationException("Classe utilitaire non instanciable");
}
public static String trim(String s) { return s.trim(); }
}Very long files are difficult to maintain and understand.
Split into smaller, focused modules.
💡 Better maintainability, easier navigation.
class User: ...
def send_email(): ...
class OrderView: ...class User: ...
def send_email(): ...
class OrderView: ...Unresolved TODOs indicate incomplete work.
Resolve or create a ticket for tracking.
💡 Clean codebase, tracked technical debt.
data = get_data()data = get_data()System.out/err.println bypasses logging framework — no log levels, no rotation, no monitoring.
Use SLF4J/Log4j2 logger with appropriate log levels (debug, info, warn, error).
💡 Structured, configurable logging with proper monitoring integration.
System.out.println("Debug: " + data);logger.debug("Processing: {}", data);Deprecated methods (Thread.stop, finalize, new Date(y,m,d)) may be removed in future JDK versions and have known issues.
Replace with modern alternatives: Thread.interrupt(), try-with-resources, java.time API.
💡 Future-proof code, better reliability and compatibility.
Date d = new Date();LocalDateTime d = LocalDateTime.now();No issues in dependencies.
✅ No issues detected in this category.
No custom rules configured
Custom rules let you detect patterns specific to your codebase. Create your first rule with:
./run_audit.py . --create-ruleThis matrix shows which Annex A controls are testable by static code analysis. It does not certify full compliance with ISO 27001 — organizational, physical and procedural controls require separate assessment.
| Control | Name | Status | Rules | Findings |
|---|---|---|---|---|
| A.5.1 | Policies for information security | Covered | 1 | — |
| A.5.10 | Acceptable use of information and other associated assets | Not applicable | 0 | — |
| A.5.11 | Return of assets | Not applicable | 0 | — |
| A.5.12 | Classification of information | Not applicable | 0 | — |
| A.5.13 | Labelling of information | Not applicable | 0 | — |
| A.5.14 | Information transfer | Covered | 1 | — |
| A.5.15 | Access control | Covered | 1 | — |
| A.5.16 | Identity management | Not applicable | 0 | — |
| A.5.17 | Authentication information | Not applicable | 0 | — |
| A.5.18 | Access rights | Covered | 1 | — |
| A.5.19 | Information security in supplier relationships | Not applicable | 0 | — |
| A.5.2 | Information security roles and responsibilities | Not applicable | 0 | — |
| A.5.20 | Addressing information security within supplier agreements | Not applicable | 0 | — |
| A.5.21 | Managing information security in the ICT supply chain | Covered | 5 | — |
| A.5.22 | Monitoring, review and change management of supplier services | Not applicable | 0 | — |
| A.5.23 | Information security for use of cloud services | Covered | 1 | — |
| A.5.24 | Information security incident management planning and preparation | Not applicable | 0 | — |
| A.5.25 | Assessment and decision on information security events | Not applicable | 0 | — |
| A.5.26 | Response to information security incidents | Not applicable | 0 | — |
| A.5.27 | Learning from information security incidents | Not applicable | 0 | — |
| A.5.28 | Collection of evidence | Not applicable | 0 | — |
| A.5.29 | Information security during disruption | Not applicable | 0 | — |
| A.5.3 | Segregation of duties | Not applicable | 0 | — |
| A.5.30 | ICT readiness for business continuity | Not applicable | 0 | — |
| A.5.31 | Legal, statutory, regulatory and contractual requirements | Not applicable | 0 | — |
| A.5.32 | Intellectual property rights | Covered | 1 | — |
| A.5.33 | Protection of records | Covered | 1 | — |
| A.5.34 | Privacy and protection of PII | Covered | 2 | — |
| A.5.35 | Independent review of information security | Not applicable | 0 | — |
| A.5.36 | Compliance with policies, rules and standards for information security | Not applicable | 0 | — |
| A.5.37 | Documented operating procedures | Covered | 1 | — |
| A.5.4 | Management responsibilities | Not applicable | 0 | — |
| A.5.5 | Contact with authorities | Not applicable | 0 | — |
| A.5.6 | Contact with special interest groups | Not applicable | 0 | — |
| A.5.7 | Threat intelligence | Not applicable | 0 | — |
| A.5.8 | Information security in project management | Not applicable | 0 | — |
| A.5.9 | Inventory of information and other associated assets | Not applicable | 0 | — |
| Control | Name | Status | Rules | Findings |
|---|---|---|---|---|
| A.6.1 | Screening | Not applicable | 0 | — |
| A.6.2 | Terms and conditions of employment | Not applicable | 0 | — |
| A.6.3 | Information security awareness, education and training | Not applicable | 0 | — |
| A.6.4 | Disciplinary process | Not applicable | 0 | — |
| A.6.5 | Responsibilities after termination or change of employment | Not applicable | 0 | — |
| A.6.6 | Confidentiality or non-disclosure agreements | Not applicable | 0 | — |
| A.6.7 | Remote working | Not applicable | 0 | — |
| A.6.8 | Information security event reporting | Not applicable | 0 | — |
| Control | Name | Status | Rules | Findings |
|---|---|---|---|---|
| A.7.1 | Physical security perimeters | Not applicable | 0 | — |
| A.7.10 | Storage media | Not applicable | 0 | — |
| A.7.11 | Supporting utilities | Not applicable | 0 | — |
| A.7.12 | Cabling security | Not applicable | 0 | — |
| A.7.13 | Equipment maintenance | Not applicable | 0 | — |
| A.7.14 | Secure disposal or re-use of equipment | Not applicable | 0 | — |
| A.7.2 | Physical entry | Not applicable | 0 | — |
| A.7.3 | Securing offices, rooms and facilities | Not applicable | 0 | — |
| A.7.4 | Physical security monitoring | Not applicable | 0 | — |
| A.7.5 | Protecting against physical and environmental threats | Not applicable | 0 | — |
| A.7.6 | Working in secure areas | Not applicable | 0 | — |
| A.7.7 | Clear desk and clear screen | Not applicable | 0 | — |
| A.7.8 | Equipment siting and protection | Not applicable | 0 | — |
| A.7.9 | Security of assets off-premises | Not applicable | 0 | — |
| Control | Name | Status | Rules | Findings |
|---|---|---|---|---|
| A.8.1 | User endpoint devices | Covered | 1 | — |
| A.8.10 | Information deletion | Covered | 1 | — |
| A.8.11 | Data masking | Covered | 1 | — |
| A.8.12 | Data leakage prevention | Issues found | 16 | 478 |
| A.8.13 | Information backup | Covered | 1 | — |
| A.8.14 | Redundancy of information processing facilities | Covered | 1 | — |
| A.8.15 | Logging | Issues found | 9 | 97 |
| A.8.16 | Monitoring activities | Covered | 1 | — |
| A.8.17 | Clock synchronization | Covered | 1 | — |
| A.8.18 | Use of privileged utility programs | Covered | 1 | — |
| A.8.19 | Installation of software on operational systems | Covered | 2 | — |
| A.8.2 | Privileged access rights | Issues found | 4 | 8 |
| A.8.20 | Networks security | Covered | 9 | — |
| A.8.21 | Security of network services | Covered | 1 | — |
| A.8.22 | Segregation of networks | Covered | 1 | — |
| A.8.23 | Web filtering | Covered | 1 | — |
| A.8.24 | Use of cryptography | Issues found | 14 | 8 |
| A.8.25 | Secure development life cycle | Issues found | 13 | 75 |
| A.8.26 | Application security requirements | Issues found | 61 | 4 |
| A.8.27 | Secure system architecture and engineering principles | Issues found | 5 | 83 |
| A.8.28 | Secure coding | Issues found | 119 | 780 |
| A.8.29 | Security testing in development and acceptance | Covered | 2 | — |
| A.8.3 | Information access restriction | Covered | 9 | — |
| A.8.30 | Outsourced development | Covered | 1 | — |
| A.8.31 | Separation of development, test and production environments | Covered | 4 | — |
| A.8.32 | Change management | Covered | 2 | — |
| A.8.33 | Test information | Covered | 1 | — |
| A.8.34 | Protection of information systems during audit testing | Covered | 1 | — |
| A.8.4 | Access to source code | Covered | 1 | — |
| A.8.5 | Secure authentication | Issues found | 4 | 1 |
| A.8.6 | Capacity management | Covered | 1 | — |
| A.8.7 | Protection against malware | Issues found | 6 | 1 |
| A.8.8 | Management of technical vulnerabilities | Issues found | 9 | 2 |
| A.8.9 | Configuration management | Issues found | 15 | 8 |
This matrix shows which ASVS requirements are testable by static code analysis (~24% SAST ceiling). It does not certify full ASVS compliance — runtime, infrastructure and procedural requirements need separate assessment.
| Requirement | Name | Level | Status | Rules | Findings |
|---|---|---|---|---|---|
| 1.2.1 | Verify that output encoding for HTML contexts prevents XSS | L1 | Covered | 8 | — |
| 1.2.10 | Verify that CSV injection is prevented | L2 | Covered | 1 | — |
| 1.2.2 | Verify that output encoding for JavaScript contexts prevents XSS | L1 | Not applicable | 0 | — |
| 1.2.3 | Verify that output encoding for URL contexts prevents injection | L1 | Not applicable | 0 | — |
| 1.2.4 | Verify that SQL queries use parameterized queries or ORM | L1 | Issues found | 18 | 1 |
| 1.2.5 | Verify that OS command injection is prevented | L1 | Issues found | 3 | 1 |
| 1.2.6 | Verify that LDAP injection is prevented | L1 | Covered | 3 | — |
| 1.2.7 | Verify that XML Path Language — Query language for XML documents; injection can allow unauthorized data access.">XPath or XML injection is prevented | L1 | Covered | 4 | — |
| 1.3.10 | Verify that format string vulnerabilities are prevented | L2 | Covered | 1 | — |
| 1.3.11 | Verify that SMTP header injection is prevented | L2 | Covered | 2 | — |
| 1.3.12 | Verify that ReDoS is prevented in regex patterns | L2 | Covered | 1 | — |
| 1.3.2 | Verify that dynamic code execution features are not used with untrusted data | L1 | Covered | 2 | — |
| 1.3.4 | Verify that XML-based vector image format for the web.">SVG scriptable content is handled safely | L1 | Covered | 1 | — |
| 1.3.6 | Verify that SSRF protections are implemented | L1 | Covered | 5 | — |
| 1.3.7 | Verify that template injection is prevented | L1 | Covered | 3 | — |
| 1.3.8 | Verify that API used for directory services; exploited in Log4Shell (CVE-2021-44228) for RCE.">JNDI injection is prevented | L1 | Covered | 1 | — |
| 1.5.1 | Verify that XML parsers are configured to prevent XXE | L1 | Issues found | 3 | 1 |
| 1.5.2 | Verify that deserialization of untrusted data is avoided | L1 | Issues found | 4 | 1 |
Not applicable
| Requirement | Name | Level | Status | Rules | Findings |
|---|---|---|---|---|---|
| 3.3.1 | Verify that cookies have Secure attribute set | L1 | Issues found | 1 | 1 |
| 3.4.1 | Verify that HSTS header is set | L1 | Covered | 1 | — |
| 3.4.2 | Verify that CORS policy is restrictive | L1 | Covered | 3 | — |
| 3.4.3 | Verify that CSP header is configured | L1 | Covered | 1 | — |
| 3.4.4 | Verify that X-Content-Type-Options is set to nosniff | L1 | Covered | 1 | — |
| 3.4.5 | Verify that Referrer-Policy header is configured | L2 | Covered | 1 | — |
| 3.4.6 | Verify that clickjacking protection is implemented | L1 | Covered | 1 | — |
| 3.5.1 | Verify that CSRF protections are enabled | L1 | Covered | 2 | — |
| 3.5.5 | Verify that postMessage origin is validated | L2 | Covered | 1 | — |
| 3.6.1 | Verify that SRI is used for external scripts | L2 | Covered | 1 | — |
| 3.7.2 | Verify that open redirect vulnerabilities are prevented | L1 | Covered | 3 | — |
| Requirement | Name | Level | Status | Rules | Findings |
|---|---|---|---|---|---|
| 5.2.2 | Verify that file uploads are validated for type and size | L1 | Covered | 1 | — |
| 5.3.2 | Verify that path traversal is prevented | L1 | Covered | 4 | — |
| Requirement | Name | Level | Status | Rules | Findings |
|---|---|---|---|---|---|
| 6.2.1 | Verify that passwords have a minimum length of 8 characters | L1 | Covered | 1 | — |
| 6.3.2 | Verify that default credentials are not used | L1 | Covered | 1 | — |
| 6.3.3 | Verify that MFA is available for sensitive operations | L2 | Covered | 5 | — |
| 6.4.2 | Verify that security questions are not used for authentication | L1 | Covered | 1 | — |
Not applicable
Not applicable
Not applicable
| Requirement | Name | Level | Status | Rules | Findings |
|---|---|---|---|---|---|
| 11.2.3 | Verify that key sizes meet minimum requirements | L1 | Covered | 1 | — |
| 11.3.1 | Verify that strong cryptographic algorithms are used | L1 | Issues found | 4 | 2 |
| 11.3.2 | Verify that deprecated algorithms are not used | L1 | Issues found | 2 | 2 |
| 11.4.1 | Verify that strong hash functions are used | L1 | Not applicable | 0 | — |
| 11.5.1 | Verify that cryptographically secure random generators are used | L1 | Issues found | 4 | 6 |
Not applicable
Not applicable
Not applicable
| Requirement | Name | Level | Status | Rules | Findings |
|---|---|---|---|---|---|
| 16.3.2 | Verify that log injection is prevented | L2 | Covered | 1 | — |
Not applicable
Coverage indicates which CSF subcategories are checked by SCA rules. Findings indicate detected issues that should be addressed for compliance.
| ID | Subcategory | Status | Rules | Findings |
|---|---|---|---|---|
| GV.SC-05 | Supply chain risk assessment is performed | Covered | 4 | — |
| ID | Subcategory | Status | Rules | Findings |
|---|---|---|---|---|
| ID.AM-01 | Hardware assets are inventoried | Not applicable | 0 | — |
| ID.AM-02 | Software assets are inventoried | Not applicable | 0 | — |
| ID.RA-01 | Vulnerabilities in assets are identified, validated, and recorded | Covered | 1 | — |
| ID.RA-02 | Cyber threat intelligence is received from forums and sources | Not applicable | 0 | — |
| ID | Subcategory | Status | Rules | Findings |
|---|---|---|---|---|
| PR.AA-01 | Identities and credentials are managed | Covered | 5 | — |
| PR.AA-02 | Identities are proofed and bound to credentials | Not applicable | 0 | — |
| PR.AA-03 | Users, services, and hardware are authenticated | Covered | 6 | — |
| PR.AA-04 | Identity assertions are protected, conveyed, and verified | Issues found | 2 | 1 |
| PR.AA-05 | Access permissions, entitlements, and authorizations are managed | Covered | 7 | — |
| PR.AT-01 | Personnel are provided awareness and training | Not applicable | 0 | — |
| PR.DS-01 | Data-at-rest is protected | Issues found | 17 | 14 |
| PR.DS-02 | Data-in-transit is protected | Issues found | 9 | 1 |
| PR.DS-10 | Confidentiality, integrity, and availability of data are protected | Issues found | 41 | 383 |
| PR.IR-01 | Networks and environments are protected | Covered | 14 | — |
| PR.IR-02 | Technology assets are managed to ensure availability | Covered | 6 | — |
| PR.PS-01 | Configuration management practices are established | Covered | 4 | — |
| PR.PS-02 | Software is maintained, replaced, and removed | Issues found | 7 | 2 |
| PR.PS-04 | Log records are generated and made available | Covered | 4 | — |
| PR.PS-05 | Installation and execution of unauthorized software is prevented | Covered | 4 | — |
| PR.PS-06 | Secure software development practices are used | Issues found | 32 | 2 |
| ID | Subcategory | Status | Rules | Findings |
|---|---|---|---|---|
| DE.CM-01 | Networks and network services are monitored | Not applicable | 0 | — |
| DE.CM-06 | External service provider activities are monitored | Not applicable | 0 | — |
| DE.CM-09 | Computing hardware and software are monitored | Covered | 3 | — |
This section lists positive findings from the audit. Each item represents a verified security or architecture good practice in your code.
Acronyms and technical terms used in this report.
| Acronym | Meaning | Description |
|---|---|---|
| API | Application Programming Interface | Communication interface between software systems. |
| ARIA | Accessible Rich Internet Applications | HTML attributes that improve accessibility for assistive technologies. |
| ASVS | Application Security Verification Standard | OWASP standard defining security requirements for web applications across 3 verification levels (L1/L2/L3). |
| CI/CD | Continuous Integration / Continuous Deployment | Automated pipeline that builds, tests and deploys code on every change. |
| CLI | Command Line Interface | Text-based interface used to interact with a program via a terminal. |
| CORS | Cross-Origin Resource Sharing | Security mechanism controlling HTTP requests between different domains. |
| CSP | Content Security Policy | HTTP header restricting allowed content sources on a web page. |
| CSRF | Cross-Site Request Forgery | Attack that forces an authenticated user to perform unwanted actions. |
| CSS | Cascading Style Sheets | Language for styling and formatting web pages. |
| CVE | Common Vulnerabilities and Exposures | Unique identifier for a known security vulnerability. |
| CVSS | Common Vulnerability Scoring System | Vulnerability severity rating system (score from 0 to 10). |
| CWE | Common Weakness Enumeration | Standardized catalog of software weakness types. |
| DOM | Document Object Model | Tree representation of an HTML document in memory. |
| DRY | Don't Repeat Yourself | Design principle that avoids code duplication. |
| Fixture | Test Fixture | Code sample (vulnerable or clean) used to validate that a detection rule fires correctly. |
| GDPR | General Data Protection Regulation | European regulation on personal data protection. |
| HSTS | HTTP Strict Transport Security | HTTP header that forces browsers to use HTTPS only, preventing downgrade attacks. |
| HTML | HyperText Markup Language | Markup language for structuring web pages. |
| HTTP/HTTPS | HyperText Transfer Protocol (Secure) | Web communication protocol. HTTPS adds encryption via TLS. |
| i18n | Internationalization | Adapting software to support multiple languages and regions. |
| IDOR | Insecure Direct Object Reference | Access control flaw where an attacker can access resources by manipulating identifiers. |
| ISO 27001 | ISO/IEC 27001:2022 | International standard for information security management systems (ISMS). Annex A defines 93 controls across 4 themes. |
| JNDI | Java Naming and Directory Interface | Java API used for directory services; exploited in Log4Shell (CVE-2021-44228) for RCE. |
| JS | JavaScript | Programming language primarily used for web development. |
| JSON | JavaScript Object Notation | Lightweight data interchange format. |
| JWT | JSON Web Token | Signed authentication token in JSON format, used for sessions. |
| LDAP | Lightweight Directory Access Protocol | Protocol for accessing and maintaining directory services (user accounts, etc.). |
| MD5 | Message Digest 5 | Obsolete and insecure hashing algorithm — should no longer be used. |
| MFA | Multi-Factor Authentication | Authentication requiring two or more verification factors (password + OTP, etc.). |
| NoSQL | Not only SQL | Non-relational databases (MongoDB, Redis, etc.) vulnerable to injection if queries are unsanitised. |
| ORM | Object-Relational Mapping | Abstraction layer between object code and relational databases. |
| OWASP | Open Web Application Security Project | Global reference for web application security best practices. |
| PII | Personally Identifiable Information | Any data that can identify an individual (name, email, SSN, etc.). Must be protected under GDPR. |
| RCE | Remote Code Execution | Critical vulnerability allowing an attacker to execute arbitrary code on the server. |
| RGPD | Règlement Général sur la Protection des Données | European data protection regulation (French name for GDPR). |
| SARIF | Static Analysis Results Interchange Format | Standardized JSON format (OASIS) for exchanging static analysis results between tools and CI/CD systems. |
| SAST | Static Application Security Testing | Source code security analysis without running the application. |
| SBOM | Software Bill of Materials | Comprehensive inventory of software components and dependencies in a project (CycloneDX format). |
| SCA | Static Code Audit | Abbreviation for StaticCodeAudit, the tool that generated this report. |
| SHA-1 | Secure Hash Algorithm 1 | Obsolete hashing algorithm — vulnerable to collision attacks. |
| SLA | Service Level Agreement | Commitment defining maximum resolution times per severity (e.g. CRITICAL: 24h, HIGH: 72h). |
| SMTP | Simple Mail Transfer Protocol | Standard protocol for sending emails; injection vulnerabilities can allow email spoofing. |
| SQL | Structured Query Language | Query language for relational databases. |
| SSH | Secure Shell | Cryptographic protocol for secure remote access to servers. |
| SSL | Secure Sockets Layer | Deprecated predecessor of TLS. Its use indicates an outdated and insecure configuration. |
| SSRF | Server-Side Request Forgery | Attack forcing a server to make requests to internal resources. |
| SSTI | Server-Side Template Injection | Injection of malicious code into a server-side template engine, potentially leading to RCE. |
| SVG | Scalable Vector Graphics | XML-based vector image format for the web. |
| Taint | Taint Analysis | Data-flow tracking technique that follows untrusted input (source) to sensitive operations (sink) to detect injection vulnerabilities. |
| TLS | Transport Layer Security | Network communication encryption protocol (successor to SSL). |
| TOCTOU | Time-of-Check to Time-of-Use | Race condition vulnerability between checking and using a resource. |
| URL | Uniform Resource Locator | Web address that identifies a resource on a network (e.g. https://example.com/path). |
| WCAG | Web Content Accessibility Guidelines | W3C web accessibility guidelines — international standard. |
| XML | eXtensible Markup Language | Structured data format widely used in configuration files, APIs, and document exchange. |
| XPath | XML Path Language | Query language for XML documents; injection can allow unauthorized data access. |
| XSS | Cross-Site Scripting | Injection of malicious scripts into a web page viewed by other users. |
| XXE | XML External Entity | XML injection attack that exploits external entity processing to read files or trigger SSRF. |