_lsy-key-scan.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. # -*- coding: utf-8 -*-
  2. """提交前体检:logs/ 下的产物里有没有混进机构密钥。
  3. 只打计数与文件名(文件名不是秘密),绝不打印密钥本身或长度以外的信息。"""
  4. import io, os, re, sys
  5. YML = "java/src/main/resources/application.yml"
  6. VAR = re.compile(r"^\$\{([A-Za-z0-9_]+):(.*)\}$")
  7. def read_block(path, top):
  8. lines = io.open(path, encoding="utf-8", errors="replace").read().split("\n")
  9. start = None
  10. for i, ln in enumerate(lines):
  11. if re.match(r"^%s:\s*$" % re.escape(top), ln):
  12. start = i; break
  13. if start is None:
  14. raise SystemExit("找不到顶层段 %s:" % top)
  15. out = {}
  16. for j in range(start + 1, len(lines)):
  17. ln = lines[j]
  18. if ln.strip() == "" or ln.lstrip().startswith("#"):
  19. continue
  20. if not ln.startswith((" ", "\t")):
  21. break
  22. m = re.match(r"^\s+([A-Za-z0-9_.\-]+):\s*(.*)$", ln)
  23. if m:
  24. out[m.group(1)] = re.split(r"\s+#", m.group(2), maxsplit=1)[0].strip().strip("'\"")
  25. return out
  26. cfg = read_block(YML, "leshouying")
  27. raw = cfg.get("key", "")
  28. m = VAR.match(raw)
  29. KEY = (os.environ.get(m.group(1)) or m.group(2)) if m else raw
  30. print("密钥长度 = %d(只打长度)" % len(KEY))
  31. if len(KEY) < 8:
  32. raise SystemExit("密钥太短,无法作为搜索针,体检作废")
  33. needle = KEY.encode("utf-8")
  34. # 正对照:密钥必然在 application.yml 里;扫不到说明扫描器/针是坏的
  35. def hits(path):
  36. try:
  37. return io.open(path, "rb").read().count(needle)
  38. except Exception:
  39. return 0
  40. pos = hits(YML)
  41. print("正对照 application.yml 命中 = %d %s" % (pos, "OK" if pos >= 1 else "!! 扫描器失效,体检作废"))
  42. if pos < 1:
  43. raise SystemExit(1)
  44. dirs = ["logs/_lsy-lc", "logs/_lsy-lc2", "logs/_lsy-lc3", "logs/_lsy-ctl"]
  45. loose = ["logs/_lsy-lifecycle.py", "logs/_lsy-lifecycle.txt",
  46. "logs/_lsy-refund-unlock.py", "logs/_lsy-refund-unlock.txt",
  47. "logs/_lsy-round3.py", "logs/_lsy-round3.txt",
  48. "logs/_lsy-close-control.py", "logs/_lsy-close-control.txt"]
  49. files = list(loose)
  50. for d in dirs:
  51. if os.path.isdir(d):
  52. for n in sorted(os.listdir(d)):
  53. files.append(os.path.join(d, n))
  54. bad, n = [], 0
  55. for f in files:
  56. n += 1
  57. c = hits(f)
  58. if c:
  59. bad.append((f, c))
  60. print("扫描文件数 = %d" % n)
  61. print("含密钥的文件数 = %d" % len(bad))
  62. for f, c in bad:
  63. print(" !! %s 命中 %d 次" % (f, c))
  64. print("结论: %s" % ("干净,可提交" if not bad else "**有泄漏,不得提交**"))