@etcsec-com/etc-collector 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (617) hide show
  1. package/.env.example +60 -0
  2. package/.env.test.example +33 -0
  3. package/.github/workflows/ci.yml +83 -0
  4. package/.github/workflows/release.yml +246 -0
  5. package/.prettierrc.json +10 -0
  6. package/CHANGELOG.md +15 -0
  7. package/Dockerfile +57 -0
  8. package/LICENSE +190 -0
  9. package/README.md +194 -0
  10. package/dist/api/controllers/audit.controller.d.ts +21 -0
  11. package/dist/api/controllers/audit.controller.d.ts.map +1 -0
  12. package/dist/api/controllers/audit.controller.js +179 -0
  13. package/dist/api/controllers/audit.controller.js.map +1 -0
  14. package/dist/api/controllers/auth.controller.d.ts +16 -0
  15. package/dist/api/controllers/auth.controller.d.ts.map +1 -0
  16. package/dist/api/controllers/auth.controller.js +146 -0
  17. package/dist/api/controllers/auth.controller.js.map +1 -0
  18. package/dist/api/controllers/export.controller.d.ts +27 -0
  19. package/dist/api/controllers/export.controller.d.ts.map +1 -0
  20. package/dist/api/controllers/export.controller.js +80 -0
  21. package/dist/api/controllers/export.controller.js.map +1 -0
  22. package/dist/api/controllers/health.controller.d.ts +5 -0
  23. package/dist/api/controllers/health.controller.d.ts.map +1 -0
  24. package/dist/api/controllers/health.controller.js +16 -0
  25. package/dist/api/controllers/health.controller.js.map +1 -0
  26. package/dist/api/controllers/jobs.controller.d.ts +13 -0
  27. package/dist/api/controllers/jobs.controller.d.ts.map +1 -0
  28. package/dist/api/controllers/jobs.controller.js +125 -0
  29. package/dist/api/controllers/jobs.controller.js.map +1 -0
  30. package/dist/api/controllers/providers.controller.d.ts +15 -0
  31. package/dist/api/controllers/providers.controller.d.ts.map +1 -0
  32. package/dist/api/controllers/providers.controller.js +112 -0
  33. package/dist/api/controllers/providers.controller.js.map +1 -0
  34. package/dist/api/dto/AuditRequest.dto.d.ts +6 -0
  35. package/dist/api/dto/AuditRequest.dto.d.ts.map +1 -0
  36. package/dist/api/dto/AuditRequest.dto.js +3 -0
  37. package/dist/api/dto/AuditRequest.dto.js.map +1 -0
  38. package/dist/api/dto/AuditResponse.dto.d.ts +17 -0
  39. package/dist/api/dto/AuditResponse.dto.d.ts.map +1 -0
  40. package/dist/api/dto/AuditResponse.dto.js +3 -0
  41. package/dist/api/dto/AuditResponse.dto.js.map +1 -0
  42. package/dist/api/dto/TokenRequest.dto.d.ts +6 -0
  43. package/dist/api/dto/TokenRequest.dto.d.ts.map +1 -0
  44. package/dist/api/dto/TokenRequest.dto.js +3 -0
  45. package/dist/api/dto/TokenRequest.dto.js.map +1 -0
  46. package/dist/api/dto/TokenResponse.dto.d.ts +12 -0
  47. package/dist/api/dto/TokenResponse.dto.d.ts.map +1 -0
  48. package/dist/api/dto/TokenResponse.dto.js +3 -0
  49. package/dist/api/dto/TokenResponse.dto.js.map +1 -0
  50. package/dist/api/middlewares/authenticate.d.ts +12 -0
  51. package/dist/api/middlewares/authenticate.d.ts.map +1 -0
  52. package/dist/api/middlewares/authenticate.js +141 -0
  53. package/dist/api/middlewares/authenticate.js.map +1 -0
  54. package/dist/api/middlewares/errorHandler.d.ts +3 -0
  55. package/dist/api/middlewares/errorHandler.d.ts.map +1 -0
  56. package/dist/api/middlewares/errorHandler.js +30 -0
  57. package/dist/api/middlewares/errorHandler.js.map +1 -0
  58. package/dist/api/middlewares/rateLimit.d.ts +3 -0
  59. package/dist/api/middlewares/rateLimit.d.ts.map +1 -0
  60. package/dist/api/middlewares/rateLimit.js +34 -0
  61. package/dist/api/middlewares/rateLimit.js.map +1 -0
  62. package/dist/api/middlewares/validate.d.ts +4 -0
  63. package/dist/api/middlewares/validate.d.ts.map +1 -0
  64. package/dist/api/middlewares/validate.js +31 -0
  65. package/dist/api/middlewares/validate.js.map +1 -0
  66. package/dist/api/routes/audit.routes.d.ts +5 -0
  67. package/dist/api/routes/audit.routes.d.ts.map +1 -0
  68. package/dist/api/routes/audit.routes.js +24 -0
  69. package/dist/api/routes/audit.routes.js.map +1 -0
  70. package/dist/api/routes/auth.routes.d.ts +6 -0
  71. package/dist/api/routes/auth.routes.d.ts.map +1 -0
  72. package/dist/api/routes/auth.routes.js +22 -0
  73. package/dist/api/routes/auth.routes.js.map +1 -0
  74. package/dist/api/routes/export.routes.d.ts +5 -0
  75. package/dist/api/routes/export.routes.d.ts.map +1 -0
  76. package/dist/api/routes/export.routes.js +16 -0
  77. package/dist/api/routes/export.routes.js.map +1 -0
  78. package/dist/api/routes/health.routes.d.ts +4 -0
  79. package/dist/api/routes/health.routes.d.ts.map +1 -0
  80. package/dist/api/routes/health.routes.js +11 -0
  81. package/dist/api/routes/health.routes.js.map +1 -0
  82. package/dist/api/routes/index.d.ts +10 -0
  83. package/dist/api/routes/index.d.ts.map +1 -0
  84. package/dist/api/routes/index.js +20 -0
  85. package/dist/api/routes/index.js.map +1 -0
  86. package/dist/api/routes/providers.routes.d.ts +5 -0
  87. package/dist/api/routes/providers.routes.d.ts.map +1 -0
  88. package/dist/api/routes/providers.routes.js +13 -0
  89. package/dist/api/routes/providers.routes.js.map +1 -0
  90. package/dist/api/validators/audit.schemas.d.ts +60 -0
  91. package/dist/api/validators/audit.schemas.d.ts.map +1 -0
  92. package/dist/api/validators/audit.schemas.js +55 -0
  93. package/dist/api/validators/audit.schemas.js.map +1 -0
  94. package/dist/api/validators/auth.schemas.d.ts +17 -0
  95. package/dist/api/validators/auth.schemas.d.ts.map +1 -0
  96. package/dist/api/validators/auth.schemas.js +21 -0
  97. package/dist/api/validators/auth.schemas.js.map +1 -0
  98. package/dist/app.d.ts +3 -0
  99. package/dist/app.d.ts.map +1 -0
  100. package/dist/app.js +62 -0
  101. package/dist/app.js.map +1 -0
  102. package/dist/config/config.schema.d.ts +65 -0
  103. package/dist/config/config.schema.d.ts.map +1 -0
  104. package/dist/config/config.schema.js +95 -0
  105. package/dist/config/config.schema.js.map +1 -0
  106. package/dist/config/index.d.ts +4 -0
  107. package/dist/config/index.d.ts.map +1 -0
  108. package/dist/config/index.js +75 -0
  109. package/dist/config/index.js.map +1 -0
  110. package/dist/container.d.ts +47 -0
  111. package/dist/container.d.ts.map +1 -0
  112. package/dist/container.js +137 -0
  113. package/dist/container.js.map +1 -0
  114. package/dist/data/database.d.ts +13 -0
  115. package/dist/data/database.d.ts.map +1 -0
  116. package/dist/data/database.js +68 -0
  117. package/dist/data/database.js.map +1 -0
  118. package/dist/data/jobs/token-cleanup.job.d.ts +23 -0
  119. package/dist/data/jobs/token-cleanup.job.d.ts.map +1 -0
  120. package/dist/data/jobs/token-cleanup.job.js +96 -0
  121. package/dist/data/jobs/token-cleanup.job.js.map +1 -0
  122. package/dist/data/migrations/migration.runner.d.ts +13 -0
  123. package/dist/data/migrations/migration.runner.d.ts.map +1 -0
  124. package/dist/data/migrations/migration.runner.js +136 -0
  125. package/dist/data/migrations/migration.runner.js.map +1 -0
  126. package/dist/data/models/Token.model.d.ts +30 -0
  127. package/dist/data/models/Token.model.d.ts.map +1 -0
  128. package/dist/data/models/Token.model.js +3 -0
  129. package/dist/data/models/Token.model.js.map +1 -0
  130. package/dist/data/repositories/token.repository.d.ts +16 -0
  131. package/dist/data/repositories/token.repository.d.ts.map +1 -0
  132. package/dist/data/repositories/token.repository.js +97 -0
  133. package/dist/data/repositories/token.repository.js.map +1 -0
  134. package/dist/providers/azure/auth.provider.d.ts +5 -0
  135. package/dist/providers/azure/auth.provider.d.ts.map +1 -0
  136. package/dist/providers/azure/auth.provider.js +13 -0
  137. package/dist/providers/azure/auth.provider.js.map +1 -0
  138. package/dist/providers/azure/azure-errors.d.ts +40 -0
  139. package/dist/providers/azure/azure-errors.d.ts.map +1 -0
  140. package/dist/providers/azure/azure-errors.js +121 -0
  141. package/dist/providers/azure/azure-errors.js.map +1 -0
  142. package/dist/providers/azure/azure-retry.d.ts +41 -0
  143. package/dist/providers/azure/azure-retry.d.ts.map +1 -0
  144. package/dist/providers/azure/azure-retry.js +85 -0
  145. package/dist/providers/azure/azure-retry.js.map +1 -0
  146. package/dist/providers/azure/graph-client.d.ts +26 -0
  147. package/dist/providers/azure/graph-client.d.ts.map +1 -0
  148. package/dist/providers/azure/graph-client.js +146 -0
  149. package/dist/providers/azure/graph-client.js.map +1 -0
  150. package/dist/providers/azure/graph.provider.d.ts +23 -0
  151. package/dist/providers/azure/graph.provider.d.ts.map +1 -0
  152. package/dist/providers/azure/graph.provider.js +161 -0
  153. package/dist/providers/azure/graph.provider.js.map +1 -0
  154. package/dist/providers/azure/queries/app.queries.d.ts +6 -0
  155. package/dist/providers/azure/queries/app.queries.d.ts.map +1 -0
  156. package/dist/providers/azure/queries/app.queries.js +9 -0
  157. package/dist/providers/azure/queries/app.queries.js.map +1 -0
  158. package/dist/providers/azure/queries/policy.queries.d.ts +6 -0
  159. package/dist/providers/azure/queries/policy.queries.d.ts.map +1 -0
  160. package/dist/providers/azure/queries/policy.queries.js +9 -0
  161. package/dist/providers/azure/queries/policy.queries.js.map +1 -0
  162. package/dist/providers/azure/queries/user.queries.d.ts +7 -0
  163. package/dist/providers/azure/queries/user.queries.d.ts.map +1 -0
  164. package/dist/providers/azure/queries/user.queries.js +10 -0
  165. package/dist/providers/azure/queries/user.queries.js.map +1 -0
  166. package/dist/providers/interfaces/IGraphProvider.d.ts +31 -0
  167. package/dist/providers/interfaces/IGraphProvider.d.ts.map +1 -0
  168. package/dist/providers/interfaces/IGraphProvider.js +3 -0
  169. package/dist/providers/interfaces/IGraphProvider.js.map +1 -0
  170. package/dist/providers/interfaces/ILDAPProvider.d.ts +37 -0
  171. package/dist/providers/interfaces/ILDAPProvider.d.ts.map +1 -0
  172. package/dist/providers/interfaces/ILDAPProvider.js +3 -0
  173. package/dist/providers/interfaces/ILDAPProvider.js.map +1 -0
  174. package/dist/providers/ldap/acl-parser.d.ts +8 -0
  175. package/dist/providers/ldap/acl-parser.d.ts.map +1 -0
  176. package/dist/providers/ldap/acl-parser.js +157 -0
  177. package/dist/providers/ldap/acl-parser.js.map +1 -0
  178. package/dist/providers/ldap/ad-mappers.d.ts +8 -0
  179. package/dist/providers/ldap/ad-mappers.d.ts.map +1 -0
  180. package/dist/providers/ldap/ad-mappers.js +162 -0
  181. package/dist/providers/ldap/ad-mappers.js.map +1 -0
  182. package/dist/providers/ldap/ldap-client.d.ts +33 -0
  183. package/dist/providers/ldap/ldap-client.d.ts.map +1 -0
  184. package/dist/providers/ldap/ldap-client.js +195 -0
  185. package/dist/providers/ldap/ldap-client.js.map +1 -0
  186. package/dist/providers/ldap/ldap-errors.d.ts +48 -0
  187. package/dist/providers/ldap/ldap-errors.d.ts.map +1 -0
  188. package/dist/providers/ldap/ldap-errors.js +120 -0
  189. package/dist/providers/ldap/ldap-errors.js.map +1 -0
  190. package/dist/providers/ldap/ldap-retry.d.ts +14 -0
  191. package/dist/providers/ldap/ldap-retry.d.ts.map +1 -0
  192. package/dist/providers/ldap/ldap-retry.js +102 -0
  193. package/dist/providers/ldap/ldap-retry.js.map +1 -0
  194. package/dist/providers/ldap/ldap-sanitizer.d.ts +12 -0
  195. package/dist/providers/ldap/ldap-sanitizer.d.ts.map +1 -0
  196. package/dist/providers/ldap/ldap-sanitizer.js +104 -0
  197. package/dist/providers/ldap/ldap-sanitizer.js.map +1 -0
  198. package/dist/providers/ldap/ldap.provider.d.ts +21 -0
  199. package/dist/providers/ldap/ldap.provider.d.ts.map +1 -0
  200. package/dist/providers/ldap/ldap.provider.js +165 -0
  201. package/dist/providers/ldap/ldap.provider.js.map +1 -0
  202. package/dist/providers/ldap/queries/computer.queries.d.ts +6 -0
  203. package/dist/providers/ldap/queries/computer.queries.d.ts.map +1 -0
  204. package/dist/providers/ldap/queries/computer.queries.js +9 -0
  205. package/dist/providers/ldap/queries/computer.queries.js.map +1 -0
  206. package/dist/providers/ldap/queries/group.queries.d.ts +6 -0
  207. package/dist/providers/ldap/queries/group.queries.d.ts.map +1 -0
  208. package/dist/providers/ldap/queries/group.queries.js +9 -0
  209. package/dist/providers/ldap/queries/group.queries.js.map +1 -0
  210. package/dist/providers/ldap/queries/user.queries.d.ts +7 -0
  211. package/dist/providers/ldap/queries/user.queries.d.ts.map +1 -0
  212. package/dist/providers/ldap/queries/user.queries.js +10 -0
  213. package/dist/providers/ldap/queries/user.queries.js.map +1 -0
  214. package/dist/providers/smb/smb.provider.d.ts +68 -0
  215. package/dist/providers/smb/smb.provider.d.ts.map +1 -0
  216. package/dist/providers/smb/smb.provider.js +382 -0
  217. package/dist/providers/smb/smb.provider.js.map +1 -0
  218. package/dist/server.d.ts +2 -0
  219. package/dist/server.d.ts.map +1 -0
  220. package/dist/server.js +44 -0
  221. package/dist/server.js.map +1 -0
  222. package/dist/services/audit/ad-audit.service.d.ts +70 -0
  223. package/dist/services/audit/ad-audit.service.d.ts.map +1 -0
  224. package/dist/services/audit/ad-audit.service.js +1019 -0
  225. package/dist/services/audit/ad-audit.service.js.map +1 -0
  226. package/dist/services/audit/attack-graph.service.d.ts +62 -0
  227. package/dist/services/audit/attack-graph.service.d.ts.map +1 -0
  228. package/dist/services/audit/attack-graph.service.js +702 -0
  229. package/dist/services/audit/attack-graph.service.js.map +1 -0
  230. package/dist/services/audit/audit.service.d.ts +4 -0
  231. package/dist/services/audit/audit.service.d.ts.map +1 -0
  232. package/dist/services/audit/audit.service.js +10 -0
  233. package/dist/services/audit/audit.service.js.map +1 -0
  234. package/dist/services/audit/azure-audit.service.d.ts +37 -0
  235. package/dist/services/audit/azure-audit.service.d.ts.map +1 -0
  236. package/dist/services/audit/azure-audit.service.js +153 -0
  237. package/dist/services/audit/azure-audit.service.js.map +1 -0
  238. package/dist/services/audit/detectors/ad/accounts.detector.d.ts +37 -0
  239. package/dist/services/audit/detectors/ad/accounts.detector.d.ts.map +1 -0
  240. package/dist/services/audit/detectors/ad/accounts.detector.js +881 -0
  241. package/dist/services/audit/detectors/ad/accounts.detector.js.map +1 -0
  242. package/dist/services/audit/detectors/ad/adcs.detector.d.ts +21 -0
  243. package/dist/services/audit/detectors/ad/adcs.detector.d.ts.map +1 -0
  244. package/dist/services/audit/detectors/ad/adcs.detector.js +227 -0
  245. package/dist/services/audit/detectors/ad/adcs.detector.js.map +1 -0
  246. package/dist/services/audit/detectors/ad/advanced.detector.d.ts +63 -0
  247. package/dist/services/audit/detectors/ad/advanced.detector.d.ts.map +1 -0
  248. package/dist/services/audit/detectors/ad/advanced.detector.js +867 -0
  249. package/dist/services/audit/detectors/ad/advanced.detector.js.map +1 -0
  250. package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts +16 -0
  251. package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts.map +1 -0
  252. package/dist/services/audit/detectors/ad/attack-paths.detector.js +369 -0
  253. package/dist/services/audit/detectors/ad/attack-paths.detector.js.map +1 -0
  254. package/dist/services/audit/detectors/ad/compliance.detector.d.ts +28 -0
  255. package/dist/services/audit/detectors/ad/compliance.detector.d.ts.map +1 -0
  256. package/dist/services/audit/detectors/ad/compliance.detector.js +896 -0
  257. package/dist/services/audit/detectors/ad/compliance.detector.js.map +1 -0
  258. package/dist/services/audit/detectors/ad/computers.detector.d.ts +30 -0
  259. package/dist/services/audit/detectors/ad/computers.detector.d.ts.map +1 -0
  260. package/dist/services/audit/detectors/ad/computers.detector.js +799 -0
  261. package/dist/services/audit/detectors/ad/computers.detector.js.map +1 -0
  262. package/dist/services/audit/detectors/ad/gpo.detector.d.ts +17 -0
  263. package/dist/services/audit/detectors/ad/gpo.detector.d.ts.map +1 -0
  264. package/dist/services/audit/detectors/ad/gpo.detector.js +257 -0
  265. package/dist/services/audit/detectors/ad/gpo.detector.js.map +1 -0
  266. package/dist/services/audit/detectors/ad/groups.detector.d.ts +19 -0
  267. package/dist/services/audit/detectors/ad/groups.detector.d.ts.map +1 -0
  268. package/dist/services/audit/detectors/ad/groups.detector.js +488 -0
  269. package/dist/services/audit/detectors/ad/groups.detector.js.map +1 -0
  270. package/dist/services/audit/detectors/ad/index.d.ts +15 -0
  271. package/dist/services/audit/detectors/ad/index.d.ts.map +1 -0
  272. package/dist/services/audit/detectors/ad/index.js +51 -0
  273. package/dist/services/audit/detectors/ad/index.js.map +1 -0
  274. package/dist/services/audit/detectors/ad/kerberos.detector.d.ts +17 -0
  275. package/dist/services/audit/detectors/ad/kerberos.detector.d.ts.map +1 -0
  276. package/dist/services/audit/detectors/ad/kerberos.detector.js +293 -0
  277. package/dist/services/audit/detectors/ad/kerberos.detector.js.map +1 -0
  278. package/dist/services/audit/detectors/ad/monitoring.detector.d.ts +23 -0
  279. package/dist/services/audit/detectors/ad/monitoring.detector.d.ts.map +1 -0
  280. package/dist/services/audit/detectors/ad/monitoring.detector.js +328 -0
  281. package/dist/services/audit/detectors/ad/monitoring.detector.js.map +1 -0
  282. package/dist/services/audit/detectors/ad/network.detector.d.ts +39 -0
  283. package/dist/services/audit/detectors/ad/network.detector.d.ts.map +1 -0
  284. package/dist/services/audit/detectors/ad/network.detector.js +257 -0
  285. package/dist/services/audit/detectors/ad/network.detector.js.map +1 -0
  286. package/dist/services/audit/detectors/ad/password.detector.d.ts +14 -0
  287. package/dist/services/audit/detectors/ad/password.detector.d.ts.map +1 -0
  288. package/dist/services/audit/detectors/ad/password.detector.js +235 -0
  289. package/dist/services/audit/detectors/ad/password.detector.js.map +1 -0
  290. package/dist/services/audit/detectors/ad/permissions.detector.d.ts +20 -0
  291. package/dist/services/audit/detectors/ad/permissions.detector.d.ts.map +1 -0
  292. package/dist/services/audit/detectors/ad/permissions.detector.js +392 -0
  293. package/dist/services/audit/detectors/ad/permissions.detector.js.map +1 -0
  294. package/dist/services/audit/detectors/ad/trusts.detector.d.ts +11 -0
  295. package/dist/services/audit/detectors/ad/trusts.detector.d.ts.map +1 -0
  296. package/dist/services/audit/detectors/ad/trusts.detector.js +186 -0
  297. package/dist/services/audit/detectors/ad/trusts.detector.js.map +1 -0
  298. package/dist/services/audit/detectors/azure/app-security.detector.d.ts +11 -0
  299. package/dist/services/audit/detectors/azure/app-security.detector.d.ts.map +1 -0
  300. package/dist/services/audit/detectors/azure/app-security.detector.js +184 -0
  301. package/dist/services/audit/detectors/azure/app-security.detector.js.map +1 -0
  302. package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts +10 -0
  303. package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts.map +1 -0
  304. package/dist/services/audit/detectors/azure/conditional-access.detector.js +130 -0
  305. package/dist/services/audit/detectors/azure/conditional-access.detector.js.map +1 -0
  306. package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts +8 -0
  307. package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts.map +1 -0
  308. package/dist/services/audit/detectors/azure/privilege-security.detector.js +113 -0
  309. package/dist/services/audit/detectors/azure/privilege-security.detector.js.map +1 -0
  310. package/dist/services/audit/detectors/azure/user-security.detector.d.ts +14 -0
  311. package/dist/services/audit/detectors/azure/user-security.detector.d.ts.map +1 -0
  312. package/dist/services/audit/detectors/azure/user-security.detector.js +198 -0
  313. package/dist/services/audit/detectors/azure/user-security.detector.js.map +1 -0
  314. package/dist/services/audit/detectors/index.d.ts +2 -0
  315. package/dist/services/audit/detectors/index.d.ts.map +1 -0
  316. package/dist/services/audit/detectors/index.js +38 -0
  317. package/dist/services/audit/detectors/index.js.map +1 -0
  318. package/dist/services/audit/response-formatter.d.ts +176 -0
  319. package/dist/services/audit/response-formatter.d.ts.map +1 -0
  320. package/dist/services/audit/response-formatter.js +240 -0
  321. package/dist/services/audit/response-formatter.js.map +1 -0
  322. package/dist/services/audit/scoring.service.d.ts +15 -0
  323. package/dist/services/audit/scoring.service.d.ts.map +1 -0
  324. package/dist/services/audit/scoring.service.js +139 -0
  325. package/dist/services/audit/scoring.service.js.map +1 -0
  326. package/dist/services/auth/crypto.service.d.ts +19 -0
  327. package/dist/services/auth/crypto.service.d.ts.map +1 -0
  328. package/dist/services/auth/crypto.service.js +135 -0
  329. package/dist/services/auth/crypto.service.js.map +1 -0
  330. package/dist/services/auth/errors.d.ts +19 -0
  331. package/dist/services/auth/errors.d.ts.map +1 -0
  332. package/dist/services/auth/errors.js +46 -0
  333. package/dist/services/auth/errors.js.map +1 -0
  334. package/dist/services/auth/token.service.d.ts +41 -0
  335. package/dist/services/auth/token.service.d.ts.map +1 -0
  336. package/dist/services/auth/token.service.js +208 -0
  337. package/dist/services/auth/token.service.js.map +1 -0
  338. package/dist/services/config/config.service.d.ts +6 -0
  339. package/dist/services/config/config.service.d.ts.map +1 -0
  340. package/dist/services/config/config.service.js +64 -0
  341. package/dist/services/config/config.service.js.map +1 -0
  342. package/dist/services/export/export.service.d.ts +28 -0
  343. package/dist/services/export/export.service.d.ts.map +1 -0
  344. package/dist/services/export/export.service.js +28 -0
  345. package/dist/services/export/export.service.js.map +1 -0
  346. package/dist/services/export/formatters/csv.formatter.d.ts +8 -0
  347. package/dist/services/export/formatters/csv.formatter.d.ts.map +1 -0
  348. package/dist/services/export/formatters/csv.formatter.js +46 -0
  349. package/dist/services/export/formatters/csv.formatter.js.map +1 -0
  350. package/dist/services/export/formatters/json.formatter.d.ts +40 -0
  351. package/dist/services/export/formatters/json.formatter.d.ts.map +1 -0
  352. package/dist/services/export/formatters/json.formatter.js +58 -0
  353. package/dist/services/export/formatters/json.formatter.js.map +1 -0
  354. package/dist/services/jobs/azure-job-runner.d.ts +38 -0
  355. package/dist/services/jobs/azure-job-runner.d.ts.map +1 -0
  356. package/dist/services/jobs/azure-job-runner.js +199 -0
  357. package/dist/services/jobs/azure-job-runner.js.map +1 -0
  358. package/dist/services/jobs/index.d.ts +4 -0
  359. package/dist/services/jobs/index.d.ts.map +1 -0
  360. package/dist/services/jobs/index.js +20 -0
  361. package/dist/services/jobs/index.js.map +1 -0
  362. package/dist/services/jobs/job-runner.d.ts +64 -0
  363. package/dist/services/jobs/job-runner.d.ts.map +1 -0
  364. package/dist/services/jobs/job-runner.js +952 -0
  365. package/dist/services/jobs/job-runner.js.map +1 -0
  366. package/dist/services/jobs/job-store.d.ts +27 -0
  367. package/dist/services/jobs/job-store.d.ts.map +1 -0
  368. package/dist/services/jobs/job-store.js +261 -0
  369. package/dist/services/jobs/job-store.js.map +1 -0
  370. package/dist/services/jobs/job.types.d.ts +67 -0
  371. package/dist/services/jobs/job.types.d.ts.map +1 -0
  372. package/dist/services/jobs/job.types.js +36 -0
  373. package/dist/services/jobs/job.types.js.map +1 -0
  374. package/dist/types/ad.types.d.ts +74 -0
  375. package/dist/types/ad.types.d.ts.map +1 -0
  376. package/dist/types/ad.types.js +3 -0
  377. package/dist/types/ad.types.js.map +1 -0
  378. package/dist/types/adcs.types.d.ts +58 -0
  379. package/dist/types/adcs.types.d.ts.map +1 -0
  380. package/dist/types/adcs.types.js +38 -0
  381. package/dist/types/adcs.types.js.map +1 -0
  382. package/dist/types/attack-graph.types.d.ts +135 -0
  383. package/dist/types/attack-graph.types.d.ts.map +1 -0
  384. package/dist/types/attack-graph.types.js +58 -0
  385. package/dist/types/attack-graph.types.js.map +1 -0
  386. package/dist/types/audit.types.d.ts +34 -0
  387. package/dist/types/audit.types.d.ts.map +1 -0
  388. package/dist/types/audit.types.js +3 -0
  389. package/dist/types/audit.types.js.map +1 -0
  390. package/dist/types/azure.types.d.ts +61 -0
  391. package/dist/types/azure.types.d.ts.map +1 -0
  392. package/dist/types/azure.types.js +3 -0
  393. package/dist/types/azure.types.js.map +1 -0
  394. package/dist/types/config.types.d.ts +63 -0
  395. package/dist/types/config.types.d.ts.map +1 -0
  396. package/dist/types/config.types.js +3 -0
  397. package/dist/types/config.types.js.map +1 -0
  398. package/dist/types/error.types.d.ts +33 -0
  399. package/dist/types/error.types.d.ts.map +1 -0
  400. package/dist/types/error.types.js +70 -0
  401. package/dist/types/error.types.js.map +1 -0
  402. package/dist/types/finding.types.d.ts +133 -0
  403. package/dist/types/finding.types.d.ts.map +1 -0
  404. package/dist/types/finding.types.js +3 -0
  405. package/dist/types/finding.types.js.map +1 -0
  406. package/dist/types/gpo.types.d.ts +39 -0
  407. package/dist/types/gpo.types.d.ts.map +1 -0
  408. package/dist/types/gpo.types.js +15 -0
  409. package/dist/types/gpo.types.js.map +1 -0
  410. package/dist/types/token.types.d.ts +26 -0
  411. package/dist/types/token.types.d.ts.map +1 -0
  412. package/dist/types/token.types.js +3 -0
  413. package/dist/types/token.types.js.map +1 -0
  414. package/dist/types/trust.types.d.ts +45 -0
  415. package/dist/types/trust.types.d.ts.map +1 -0
  416. package/dist/types/trust.types.js +71 -0
  417. package/dist/types/trust.types.js.map +1 -0
  418. package/dist/utils/entity-converter.d.ts +17 -0
  419. package/dist/utils/entity-converter.d.ts.map +1 -0
  420. package/dist/utils/entity-converter.js +285 -0
  421. package/dist/utils/entity-converter.js.map +1 -0
  422. package/dist/utils/graph.util.d.ts +66 -0
  423. package/dist/utils/graph.util.d.ts.map +1 -0
  424. package/dist/utils/graph.util.js +382 -0
  425. package/dist/utils/graph.util.js.map +1 -0
  426. package/dist/utils/logger.d.ts +7 -0
  427. package/dist/utils/logger.d.ts.map +1 -0
  428. package/dist/utils/logger.js +86 -0
  429. package/dist/utils/logger.js.map +1 -0
  430. package/dist/utils/type-name-normalizer.d.ts +5 -0
  431. package/dist/utils/type-name-normalizer.d.ts.map +1 -0
  432. package/dist/utils/type-name-normalizer.js +218 -0
  433. package/dist/utils/type-name-normalizer.js.map +1 -0
  434. package/docker-compose.yml +26 -0
  435. package/docs/api/README.md +178 -0
  436. package/docs/api/openapi.yaml +1524 -0
  437. package/eslint.config.js +54 -0
  438. package/jest.config.js +38 -0
  439. package/package.json +97 -0
  440. package/scripts/fetch-ad-cert.sh +142 -0
  441. package/src/.gitkeep +0 -0
  442. package/src/api/.gitkeep +0 -0
  443. package/src/api/controllers/.gitkeep +0 -0
  444. package/src/api/controllers/audit.controller.ts +313 -0
  445. package/src/api/controllers/auth.controller.ts +258 -0
  446. package/src/api/controllers/export.controller.ts +153 -0
  447. package/src/api/controllers/health.controller.ts +16 -0
  448. package/src/api/controllers/jobs.controller.ts +187 -0
  449. package/src/api/controllers/providers.controller.ts +165 -0
  450. package/src/api/dto/.gitkeep +0 -0
  451. package/src/api/dto/AuditRequest.dto.ts +8 -0
  452. package/src/api/dto/AuditResponse.dto.ts +19 -0
  453. package/src/api/dto/TokenRequest.dto.ts +8 -0
  454. package/src/api/dto/TokenResponse.dto.ts +14 -0
  455. package/src/api/middlewares/.gitkeep +0 -0
  456. package/src/api/middlewares/authenticate.ts +203 -0
  457. package/src/api/middlewares/errorHandler.ts +54 -0
  458. package/src/api/middlewares/rateLimit.ts +35 -0
  459. package/src/api/middlewares/validate.ts +32 -0
  460. package/src/api/routes/.gitkeep +0 -0
  461. package/src/api/routes/audit.routes.ts +77 -0
  462. package/src/api/routes/auth.routes.ts +71 -0
  463. package/src/api/routes/export.routes.ts +34 -0
  464. package/src/api/routes/health.routes.ts +14 -0
  465. package/src/api/routes/index.ts +40 -0
  466. package/src/api/routes/providers.routes.ts +24 -0
  467. package/src/api/validators/.gitkeep +0 -0
  468. package/src/api/validators/audit.schemas.ts +59 -0
  469. package/src/api/validators/auth.schemas.ts +59 -0
  470. package/src/app.ts +87 -0
  471. package/src/config/.gitkeep +0 -0
  472. package/src/config/config.schema.ts +108 -0
  473. package/src/config/index.ts +82 -0
  474. package/src/container.ts +221 -0
  475. package/src/data/.gitkeep +0 -0
  476. package/src/data/database.ts +78 -0
  477. package/src/data/jobs/token-cleanup.job.ts +166 -0
  478. package/src/data/migrations/.gitkeep +0 -0
  479. package/src/data/migrations/001_initial_schema.sql +47 -0
  480. package/src/data/migrations/migration.runner.ts +125 -0
  481. package/src/data/models/.gitkeep +0 -0
  482. package/src/data/models/Token.model.ts +35 -0
  483. package/src/data/repositories/.gitkeep +0 -0
  484. package/src/data/repositories/token.repository.ts +160 -0
  485. package/src/providers/.gitkeep +0 -0
  486. package/src/providers/azure/.gitkeep +0 -0
  487. package/src/providers/azure/auth.provider.ts +14 -0
  488. package/src/providers/azure/azure-errors.ts +189 -0
  489. package/src/providers/azure/azure-retry.ts +168 -0
  490. package/src/providers/azure/graph-client.ts +315 -0
  491. package/src/providers/azure/graph.provider.ts +294 -0
  492. package/src/providers/azure/queries/app.queries.ts +9 -0
  493. package/src/providers/azure/queries/policy.queries.ts +9 -0
  494. package/src/providers/azure/queries/user.queries.ts +10 -0
  495. package/src/providers/interfaces/.gitkeep +0 -0
  496. package/src/providers/interfaces/IGraphProvider.ts +117 -0
  497. package/src/providers/interfaces/ILDAPProvider.ts +142 -0
  498. package/src/providers/ldap/.gitkeep +0 -0
  499. package/src/providers/ldap/acl-parser.ts +231 -0
  500. package/src/providers/ldap/ad-mappers.ts +280 -0
  501. package/src/providers/ldap/ldap-client.ts +259 -0
  502. package/src/providers/ldap/ldap-errors.ts +188 -0
  503. package/src/providers/ldap/ldap-retry.ts +267 -0
  504. package/src/providers/ldap/ldap-sanitizer.ts +273 -0
  505. package/src/providers/ldap/ldap.provider.ts +293 -0
  506. package/src/providers/ldap/queries/computer.queries.ts +9 -0
  507. package/src/providers/ldap/queries/group.queries.ts +9 -0
  508. package/src/providers/ldap/queries/user.queries.ts +10 -0
  509. package/src/providers/smb/smb.provider.ts +653 -0
  510. package/src/server.ts +60 -0
  511. package/src/services/.gitkeep +0 -0
  512. package/src/services/audit/.gitkeep +0 -0
  513. package/src/services/audit/ad-audit.service.ts +1481 -0
  514. package/src/services/audit/attack-graph.service.ts +1104 -0
  515. package/src/services/audit/audit.service.ts +12 -0
  516. package/src/services/audit/azure-audit.service.ts +286 -0
  517. package/src/services/audit/detectors/ad/accounts.detector.ts +1232 -0
  518. package/src/services/audit/detectors/ad/adcs.detector.ts +449 -0
  519. package/src/services/audit/detectors/ad/advanced.detector.ts +1270 -0
  520. package/src/services/audit/detectors/ad/attack-paths.detector.ts +600 -0
  521. package/src/services/audit/detectors/ad/compliance.detector.ts +1421 -0
  522. package/src/services/audit/detectors/ad/computers.detector.ts +1188 -0
  523. package/src/services/audit/detectors/ad/gpo.detector.ts +485 -0
  524. package/src/services/audit/detectors/ad/groups.detector.ts +685 -0
  525. package/src/services/audit/detectors/ad/index.ts +84 -0
  526. package/src/services/audit/detectors/ad/kerberos.detector.ts +424 -0
  527. package/src/services/audit/detectors/ad/monitoring.detector.ts +501 -0
  528. package/src/services/audit/detectors/ad/network.detector.ts +538 -0
  529. package/src/services/audit/detectors/ad/password.detector.ts +324 -0
  530. package/src/services/audit/detectors/ad/permissions.detector.ts +637 -0
  531. package/src/services/audit/detectors/ad/trusts.detector.ts +315 -0
  532. package/src/services/audit/detectors/azure/app-security.detector.ts +246 -0
  533. package/src/services/audit/detectors/azure/conditional-access.detector.ts +186 -0
  534. package/src/services/audit/detectors/azure/privilege-security.detector.ts +176 -0
  535. package/src/services/audit/detectors/azure/user-security.detector.ts +280 -0
  536. package/src/services/audit/detectors/index.ts +18 -0
  537. package/src/services/audit/response-formatter.ts +604 -0
  538. package/src/services/audit/scoring.service.ts +234 -0
  539. package/src/services/auth/.gitkeep +0 -0
  540. package/src/services/auth/crypto.service.ts +230 -0
  541. package/src/services/auth/errors.ts +47 -0
  542. package/src/services/auth/token.service.ts +420 -0
  543. package/src/services/config/.gitkeep +0 -0
  544. package/src/services/config/config.service.ts +75 -0
  545. package/src/services/export/.gitkeep +0 -0
  546. package/src/services/export/export.service.ts +99 -0
  547. package/src/services/export/formatters/csv.formatter.ts +124 -0
  548. package/src/services/export/formatters/json.formatter.ts +160 -0
  549. package/src/services/jobs/azure-job-runner.ts +312 -0
  550. package/src/services/jobs/index.ts +9 -0
  551. package/src/services/jobs/job-runner.ts +1280 -0
  552. package/src/services/jobs/job-store.ts +384 -0
  553. package/src/services/jobs/job.types.ts +182 -0
  554. package/src/types/.gitkeep +0 -0
  555. package/src/types/ad.types.ts +91 -0
  556. package/src/types/adcs.types.ts +107 -0
  557. package/src/types/attack-graph.types.ts +260 -0
  558. package/src/types/audit.types.ts +42 -0
  559. package/src/types/azure.types.ts +68 -0
  560. package/src/types/config.types.ts +79 -0
  561. package/src/types/error.types.ts +69 -0
  562. package/src/types/finding.types.ts +284 -0
  563. package/src/types/gpo.types.ts +72 -0
  564. package/src/types/smb2.d.ts +73 -0
  565. package/src/types/token.types.ts +32 -0
  566. package/src/types/trust.types.ts +140 -0
  567. package/src/utils/.gitkeep +0 -0
  568. package/src/utils/entity-converter.ts +453 -0
  569. package/src/utils/graph.util.ts +609 -0
  570. package/src/utils/logger.ts +111 -0
  571. package/src/utils/type-name-normalizer.ts +302 -0
  572. package/tests/.gitkeep +0 -0
  573. package/tests/e2e/.gitkeep +0 -0
  574. package/tests/fixtures/.gitkeep +0 -0
  575. package/tests/integration/.gitkeep +0 -0
  576. package/tests/integration/README.md +156 -0
  577. package/tests/integration/ad-audit.integration.test.ts +216 -0
  578. package/tests/integration/api/.gitkeep +0 -0
  579. package/tests/integration/api/endpoints.integration.test.ts +431 -0
  580. package/tests/integration/auth/jwt-authentication.integration.test.ts +358 -0
  581. package/tests/integration/providers/.gitkeep +0 -0
  582. package/tests/integration/providers/azure-basic.integration.test.ts +167 -0
  583. package/tests/integration/providers/ldap-basic.integration.test.ts +152 -0
  584. package/tests/integration/providers/ldap-connectivity.test.ts +44 -0
  585. package/tests/integration/providers/ldap-provider.integration.test.ts +347 -0
  586. package/tests/mocks/.gitkeep +0 -0
  587. package/tests/setup.ts +16 -0
  588. package/tests/unit/.gitkeep +0 -0
  589. package/tests/unit/api/middlewares/authenticate.test.ts +446 -0
  590. package/tests/unit/providers/.gitkeep +0 -0
  591. package/tests/unit/providers/azure/azure-errors.test.ts +193 -0
  592. package/tests/unit/providers/azure/azure-retry.test.ts +254 -0
  593. package/tests/unit/providers/azure/graph-provider.test.ts +313 -0
  594. package/tests/unit/providers/ldap/ad-mappers.test.ts +392 -0
  595. package/tests/unit/providers/ldap/ldap-provider.test.ts +376 -0
  596. package/tests/unit/providers/ldap/ldap-retry.test.ts +377 -0
  597. package/tests/unit/providers/ldap/ldap-sanitizer.test.ts +301 -0
  598. package/tests/unit/sample.test.ts +19 -0
  599. package/tests/unit/services/.gitkeep +0 -0
  600. package/tests/unit/services/audit/detectors/ad/accounts.detector.test.ts +393 -0
  601. package/tests/unit/services/audit/detectors/ad/advanced.detector.test.ts +380 -0
  602. package/tests/unit/services/audit/detectors/ad/computers.detector.test.ts +440 -0
  603. package/tests/unit/services/audit/detectors/ad/groups.detector.test.ts +276 -0
  604. package/tests/unit/services/audit/detectors/ad/kerberos.detector.test.ts +215 -0
  605. package/tests/unit/services/audit/detectors/ad/password.detector.test.ts +226 -0
  606. package/tests/unit/services/audit/detectors/ad/permissions.detector.test.ts +244 -0
  607. package/tests/unit/services/audit/detectors/azure/app-security.detector.test.ts +349 -0
  608. package/tests/unit/services/audit/detectors/azure/conditional-access.detector.test.ts +374 -0
  609. package/tests/unit/services/audit/detectors/azure/privilege-security.detector.test.ts +374 -0
  610. package/tests/unit/services/audit/detectors/azure/user-security.detector.test.ts +297 -0
  611. package/tests/unit/services/auth/crypto.service.test.ts +296 -0
  612. package/tests/unit/services/auth/token.service.test.ts +579 -0
  613. package/tests/unit/services/export/export.service.test.ts +241 -0
  614. package/tests/unit/services/export/formatters/csv.formatter.test.ts +270 -0
  615. package/tests/unit/services/export/formatters/json.formatter.test.ts +258 -0
  616. package/tests/unit/utils/.gitkeep +0 -0
  617. package/tsconfig.json +50 -0
@@ -0,0 +1,485 @@
1
+ /**
2
+ * GPO Security Vulnerability Detector
3
+ *
4
+ * Analyzes Group Policy Objects for security misconfigurations.
5
+ *
6
+ * Vulnerabilities detected (9):
7
+ * CRITICAL (1) - Phase 4:
8
+ * - GPO_PASSWORD_IN_SYSVOL: Passwords found in GPO preferences
9
+ *
10
+ * HIGH (2):
11
+ * - GPO_DANGEROUS_PERMISSIONS: Non-admin can edit GPO linked to sensitive OUs
12
+ * - GPO_WEAK_PASSWORD_POLICY: GPO with password length < 12 characters
13
+ *
14
+ * MEDIUM (5):
15
+ * - GPO_LAPS_NOT_DEPLOYED: No LAPS deployment GPO found
16
+ * - GPO_DISABLED_BUT_LINKED: GPO disabled but still linked
17
+ * - GPO_NO_SECURITY_FILTERING: GPO without security filtering
18
+ * - GPO_AUTHENTICATED_USERS_APPLY: GPO applies to all Authenticated Users
19
+ * - GPO_ORPHANED: Orphaned GPO (Phase 4)
20
+ *
21
+ * LOW (1):
22
+ * - GPO_UNLINKED: GPO exists but not linked anywhere
23
+ */
24
+
25
+ import { Finding } from '../../../../types/finding.types';
26
+ import {
27
+ ADGPO,
28
+ GPOLink,
29
+ GPOAclEntry,
30
+ GPO_FLAG_ALL_DISABLED,
31
+ LAPS_CSE_GUID,
32
+ LAPS_LEGACY_CSE_GUID,
33
+ } from '../../../../types/gpo.types';
34
+
35
+ // Well-known SIDs for security filtering analysis
36
+ const SID_AUTHENTICATED_USERS = 'S-1-5-11';
37
+ const SID_EVERYONE = 'S-1-1-0';
38
+ const SID_DOMAIN_COMPUTERS = '-515'; // Ends with this RID
39
+
40
+ // "Apply Group Policy" extended right GUID
41
+ const APPLY_GROUP_POLICY_RIGHT = 0x00000004; // Read + Execute equivalent for GPO
42
+
43
+ /**
44
+ * Check if GPO has LAPS Client-Side Extension
45
+ */
46
+ function hasLapsCse(gpo: ADGPO): boolean {
47
+ const extensions = gpo.gPCMachineExtensionNames || '';
48
+ return extensions.includes(LAPS_CSE_GUID) || extensions.includes(LAPS_LEGACY_CSE_GUID);
49
+ }
50
+
51
+ /**
52
+ * GPO_DANGEROUS_PERMISSIONS: Non-admin can edit GPO
53
+ * Note: Requires ACL analysis - placeholder for now
54
+ */
55
+ export function detectGpoDangerousPermissions(
56
+ gpos: ADGPO[],
57
+ _links: GPOLink[],
58
+ _includeDetails: boolean
59
+ ): Finding {
60
+ // Would analyze nTSecurityDescriptor on GPO objects for:
61
+ // - GenericAll, GenericWrite, WriteDacl, WriteOwner, WriteProperty
62
+ // granted to non-admin principals (Domain Users, Authenticated Users, etc.)
63
+
64
+ return {
65
+ type: 'GPO_DANGEROUS_PERMISSIONS',
66
+ severity: 'high',
67
+ category: 'gpo',
68
+ title: 'GPO Permissions Review Required',
69
+ description:
70
+ 'Group Policy Objects should be reviewed for overly permissive ACLs that allow non-administrators to modify GPO settings.',
71
+ count: 0, // Placeholder until ACL analysis implemented
72
+ affectedEntities: undefined,
73
+ details: {
74
+ note: 'Manual review of GPO ACLs recommended. Check for non-admin principals with write access.',
75
+ gposToReview: gpos.length,
76
+ },
77
+ };
78
+ }
79
+
80
+ /**
81
+ * GPO_LAPS_NOT_DEPLOYED: No LAPS deployment GPO found
82
+ */
83
+ export function detectGpoLapsNotDeployed(
84
+ gpos: ADGPO[],
85
+ links: GPOLink[],
86
+ _includeDetails: boolean
87
+ ): Finding {
88
+ // Check if any GPO has LAPS CSE and is linked
89
+ const lapsGpos = gpos.filter((gpo) => hasLapsCse(gpo));
90
+ const linkedLapsGpos = lapsGpos.filter((gpo) =>
91
+ links.some((link) => link.gpoGuid.toLowerCase() === gpo.cn.toLowerCase() && !link.disabled)
92
+ );
93
+
94
+ const noLapsDeployed = linkedLapsGpos.length === 0;
95
+
96
+ return {
97
+ type: 'GPO_LAPS_NOT_DEPLOYED',
98
+ severity: 'medium',
99
+ category: 'gpo',
100
+ title: 'LAPS Not Deployed via GPO',
101
+ description:
102
+ 'No active Group Policy Object was found deploying LAPS (Local Administrator Password Solution). This leaves local admin passwords vulnerable to reuse attacks.',
103
+ count: noLapsDeployed ? 1 : 0,
104
+ affectedEntities: undefined,
105
+ details: {
106
+ lapsGposFound: lapsGpos.length,
107
+ linkedLapsGpos: linkedLapsGpos.length,
108
+ note: noLapsDeployed
109
+ ? 'LAPS not deployed - local admin passwords are not being rotated.'
110
+ : 'LAPS is deployed via GPO.',
111
+ recommendation: noLapsDeployed
112
+ ? 'Deploy LAPS via GPO to manage local administrator passwords.'
113
+ : undefined,
114
+ },
115
+ };
116
+ }
117
+
118
+ /**
119
+ * GPO_WEAK_PASSWORD_POLICY: GPO with weak password settings
120
+ * Note: Requires reading GptTmpl.inf via SMB - check domain policy instead
121
+ */
122
+ export function detectGpoWeakPasswordPolicy(
123
+ _gpos: ADGPO[],
124
+ _links: GPOLink[],
125
+ domainPasswordPolicy: { minPasswordLength?: number } | null,
126
+ includeDetails: boolean
127
+ ): Finding {
128
+ const minLength = domainPasswordPolicy?.minPasswordLength ?? 0;
129
+ const isWeak = minLength < 12;
130
+
131
+ return {
132
+ type: 'GPO_WEAK_PASSWORD_POLICY',
133
+ severity: 'medium',
134
+ category: 'gpo',
135
+ title: 'Weak Password Policy',
136
+ description: `Domain password policy requires only ${minLength} characters minimum. Microsoft recommends at least 12 characters for standard accounts, 14+ for privileged accounts.`,
137
+ count: isWeak ? 1 : 0,
138
+ affectedEntities: includeDetails && isWeak ? ['Default Domain Policy'] : undefined,
139
+ details: isWeak
140
+ ? {
141
+ currentMinLength: minLength,
142
+ recommendedMinLength: 12,
143
+ }
144
+ : undefined,
145
+ };
146
+ }
147
+
148
+ /**
149
+ * GPO_UNLINKED: GPO exists but not linked anywhere
150
+ */
151
+ export function detectGpoUnlinked(
152
+ gpos: ADGPO[],
153
+ links: GPOLink[],
154
+ includeDetails: boolean
155
+ ): Finding {
156
+ // Find GPOs that have no links
157
+ const linkedGuids = new Set(links.map((l) => l.gpoGuid.toLowerCase()));
158
+ const unlinkedGpos = gpos.filter((gpo) => !linkedGuids.has(gpo.cn.toLowerCase()));
159
+
160
+ // Exclude Default Domain Policy and Default Domain Controllers Policy
161
+ const excludeGuids = [
162
+ '31B2F340-016D-11D2-945F-00C04FB984F9', // Default Domain Policy
163
+ '6AC1786C-016F-11D2-945F-00C04FB984F9', // Default Domain Controllers Policy
164
+ ];
165
+
166
+ const relevantUnlinked = unlinkedGpos.filter(
167
+ (gpo) => !excludeGuids.some((guid) => gpo.cn.toUpperCase().includes(guid))
168
+ );
169
+
170
+ return {
171
+ type: 'GPO_UNLINKED',
172
+ severity: 'low',
173
+ category: 'gpo',
174
+ title: 'Unlinked Group Policy Objects',
175
+ description:
176
+ 'GPOs exist that are not linked to any OU, domain, or site. These may be orphaned or indicate incomplete deployment.',
177
+ count: relevantUnlinked.length,
178
+ affectedEntities: includeDetails
179
+ ? relevantUnlinked.map((gpo) => gpo.displayName || gpo.cn)
180
+ : undefined,
181
+ };
182
+ }
183
+
184
+ /**
185
+ * GPO_DISABLED_BUT_LINKED: GPO is disabled but still linked
186
+ */
187
+ export function detectGpoDisabledButLinked(
188
+ gpos: ADGPO[],
189
+ links: GPOLink[],
190
+ includeDetails: boolean
191
+ ): Finding {
192
+ // Find GPOs that are disabled (flags = 3) but have active links
193
+ const disabledGpos = gpos.filter((gpo) => gpo.flags === GPO_FLAG_ALL_DISABLED);
194
+
195
+ const disabledButLinked = disabledGpos.filter((gpo) =>
196
+ links.some((link) => link.gpoGuid.toLowerCase() === gpo.cn.toLowerCase() && !link.disabled)
197
+ );
198
+
199
+ return {
200
+ type: 'GPO_DISABLED_BUT_LINKED',
201
+ severity: 'medium',
202
+ category: 'gpo',
203
+ title: 'Disabled GPO Still Linked',
204
+ description:
205
+ 'GPOs are disabled (both user and computer settings) but remain linked. This may indicate configuration drift or incomplete changes.',
206
+ count: disabledButLinked.length,
207
+ affectedEntities: includeDetails
208
+ ? disabledButLinked.map((gpo) => gpo.displayName || gpo.cn)
209
+ : undefined,
210
+ };
211
+ }
212
+
213
+ /**
214
+ * GPO_NO_SECURITY_FILTERING: GPO without explicit security filtering
215
+ * GPO applies to all objects in the linked OU without restrictions
216
+ */
217
+ export function detectGpoNoSecurityFiltering(
218
+ gpos: ADGPO[],
219
+ links: GPOLink[],
220
+ gpoAcls: GPOAclEntry[],
221
+ includeDetails: boolean
222
+ ): Finding {
223
+ // Get linked GPO GUIDs
224
+ const linkedGuids = new Set(
225
+ links.filter((l) => !l.disabled).map((l) => l.gpoGuid.toLowerCase())
226
+ );
227
+
228
+ // Find GPOs that are linked but have no security filtering
229
+ // Security filtering = only specific groups have "Apply Group Policy" right
230
+ // No filtering = Authenticated Users or Everyone has Apply right
231
+ const noFiltering: ADGPO[] = [];
232
+
233
+ for (const gpo of gpos) {
234
+ // Only check linked GPOs
235
+ if (!linkedGuids.has(gpo.cn.toLowerCase())) continue;
236
+
237
+ // Get ACLs for this GPO
238
+ const aclsForGpo = gpoAcls.filter(
239
+ (acl) => acl.gpoDn.toLowerCase() === gpo.dn.toLowerCase()
240
+ );
241
+
242
+ // If no ACL data, skip (can't determine)
243
+ if (aclsForGpo.length === 0) continue;
244
+
245
+ // Check if Authenticated Users or Everyone has Apply permission
246
+ const hasUnrestrictedApply = aclsForGpo.some(
247
+ (acl) =>
248
+ (acl.trusteeSid === SID_AUTHENTICATED_USERS || acl.trusteeSid === SID_EVERYONE) &&
249
+ (acl.accessMask & APPLY_GROUP_POLICY_RIGHT) !== 0
250
+ );
251
+
252
+ // Check if there's any specific group filtering (exclude auth users and everyone)
253
+ const hasSpecificFiltering = aclsForGpo.some(
254
+ (acl) =>
255
+ acl.trusteeSid !== SID_AUTHENTICATED_USERS &&
256
+ acl.trusteeSid !== SID_EVERYONE &&
257
+ !acl.trusteeSid.endsWith(SID_DOMAIN_COMPUTERS) &&
258
+ (acl.accessMask & APPLY_GROUP_POLICY_RIGHT) !== 0
259
+ );
260
+
261
+ // No filtering if auth users/everyone can apply and no specific groups defined
262
+ if (hasUnrestrictedApply && !hasSpecificFiltering) {
263
+ noFiltering.push(gpo);
264
+ }
265
+ }
266
+
267
+ return {
268
+ type: 'GPO_NO_SECURITY_FILTERING',
269
+ severity: 'medium',
270
+ category: 'gpo',
271
+ title: 'GPO Without Security Filtering',
272
+ description:
273
+ 'GPOs that apply to all Authenticated Users or Everyone without specific security filtering. Consider restricting GPO application to specific groups.',
274
+ count: noFiltering.length,
275
+ affectedEntities: includeDetails
276
+ ? noFiltering.map((gpo) => gpo.displayName || gpo.cn)
277
+ : undefined,
278
+ details:
279
+ noFiltering.length > 0
280
+ ? {
281
+ recommendation:
282
+ 'Apply security filtering to restrict GPO application to specific groups.',
283
+ }
284
+ : undefined,
285
+ };
286
+ }
287
+
288
+ /**
289
+ * GPO_AUTHENTICATED_USERS_APPLY: GPO explicitly grants Apply to Authenticated Users
290
+ * This is the default but may be unintended for sensitive GPOs
291
+ */
292
+ export function detectGpoAuthenticatedUsersApply(
293
+ gpos: ADGPO[],
294
+ links: GPOLink[],
295
+ gpoAcls: GPOAclEntry[],
296
+ includeDetails: boolean
297
+ ): Finding {
298
+ // Get linked GPO GUIDs
299
+ const linkedGuids = new Set(
300
+ links.filter((l) => !l.disabled).map((l) => l.gpoGuid.toLowerCase())
301
+ );
302
+
303
+ // Find GPOs where Authenticated Users has explicit Apply permission
304
+ const authUsersApply: ADGPO[] = [];
305
+
306
+ for (const gpo of gpos) {
307
+ // Only check linked GPOs
308
+ if (!linkedGuids.has(gpo.cn.toLowerCase())) continue;
309
+
310
+ // Get ACLs for this GPO
311
+ const aclsForGpo = gpoAcls.filter(
312
+ (acl) => acl.gpoDn.toLowerCase() === gpo.dn.toLowerCase()
313
+ );
314
+
315
+ // If no ACL data, skip
316
+ if (aclsForGpo.length === 0) continue;
317
+
318
+ // Check if Authenticated Users specifically has Apply permission
319
+ const authUsersHasApply = aclsForGpo.some(
320
+ (acl) =>
321
+ acl.trusteeSid === SID_AUTHENTICATED_USERS &&
322
+ (acl.accessMask & APPLY_GROUP_POLICY_RIGHT) !== 0
323
+ );
324
+
325
+ if (authUsersHasApply) {
326
+ authUsersApply.push(gpo);
327
+ }
328
+ }
329
+
330
+ return {
331
+ type: 'GPO_AUTHENTICATED_USERS_APPLY',
332
+ severity: 'medium',
333
+ category: 'gpo',
334
+ title: 'GPO Applies to All Authenticated Users',
335
+ description:
336
+ 'GPOs with Authenticated Users granted the "Apply Group Policy" permission. This is the default but may be too broad for sensitive policies.',
337
+ count: authUsersApply.length,
338
+ affectedEntities: includeDetails
339
+ ? authUsersApply.map((gpo) => gpo.displayName || gpo.cn)
340
+ : undefined,
341
+ details:
342
+ authUsersApply.length > 0
343
+ ? {
344
+ recommendation:
345
+ 'Review if all GPOs should apply to all users. Consider using security filtering for sensitive policies.',
346
+ note: 'This is informational - Authenticated Users is the default.',
347
+ }
348
+ : undefined,
349
+ };
350
+ }
351
+
352
+ /**
353
+ * Detect GPOs with passwords stored in SYSVOL (cPassword)
354
+ *
355
+ * MS14-025 patched this, but old GPOs may still contain cleartext passwords
356
+ * in Groups.xml, Services.xml, Scheduledtasks.xml, etc.
357
+ *
358
+ * @param gpos - Array of GPOs
359
+ * @param _links - Array of GPO links (not used)
360
+ * @param includeDetails - Whether to include affected entity details
361
+ * @returns Finding for GPO_PASSWORD_IN_SYSVOL
362
+ */
363
+ export function detectGpoPasswordInSysvol(
364
+ gpos: ADGPO[],
365
+ _links: GPOLink[],
366
+ includeDetails: boolean
367
+ ): Finding {
368
+ // Check GPO flags or attributes that might indicate password presence
369
+ // This would ideally need SYSVOL file content reading
370
+ // For now, check for GPOs with "cpassword" mentioned or old-style preferences
371
+ const affected = gpos.filter((gpo) => {
372
+ const gpoName = (gpo.displayName || gpo.cn || '').toLowerCase();
373
+ const gpoPath = (gpo.gPCFileSysPath || '').toLowerCase();
374
+
375
+ // GPOs that commonly contain passwords
376
+ const riskyPatterns = [
377
+ 'password',
378
+ 'credential',
379
+ 'local admin',
380
+ 'service account',
381
+ 'scheduled task',
382
+ 'drive map',
383
+ ];
384
+
385
+ return riskyPatterns.some(
386
+ (pattern) => gpoName.includes(pattern) || gpoPath.includes(pattern)
387
+ );
388
+ });
389
+
390
+ return {
391
+ type: 'GPO_PASSWORD_IN_SYSVOL',
392
+ severity: 'critical',
393
+ category: 'gpo',
394
+ title: 'Potential Passwords in GPO SYSVOL',
395
+ description:
396
+ 'GPOs that may contain cleartext passwords in SYSVOL (cPassword vulnerability MS14-025). ' +
397
+ 'Group Policy Preferences stored passwords that can be easily decrypted.',
398
+ count: affected.length,
399
+ affectedEntities: includeDetails
400
+ ? affected.map((g) => g.displayName || g.cn || g.dn)
401
+ : undefined,
402
+ details: {
403
+ note: affected.length > 0
404
+ ? `Found ${affected.length} GPO(s) with names suggesting password storage. Manual SYSVOL scan required.`
405
+ : 'No GPOs with suspicious names found. Manual SYSVOL scan still recommended.',
406
+ recommendation:
407
+ 'Scan SYSVOL for Groups.xml, Services.xml, ScheduledTasks.xml, DataSources.xml containing cpassword. ' +
408
+ 'Use tools like Get-GPPPassword or gpp-decrypt.',
409
+ reference: 'MS14-025',
410
+ gposScanned: gpos.length,
411
+ },
412
+ };
413
+ }
414
+
415
+ /**
416
+ * Detect orphaned GPOs
417
+ *
418
+ * GPOs that exist in AD but have missing SYSVOL content, or vice versa.
419
+ *
420
+ * @param gpos - Array of GPOs
421
+ * @param _links - Array of GPO links (not used)
422
+ * @param includeDetails - Whether to include affected entity details
423
+ * @returns Finding for GPO_ORPHANED
424
+ */
425
+ export function detectGpoOrphaned(
426
+ gpos: ADGPO[],
427
+ _links: GPOLink[],
428
+ includeDetails: boolean
429
+ ): Finding {
430
+ // Check for GPOs with potential orphan indicators
431
+ // A proper check would compare AD GPOs vs SYSVOL folders
432
+ const affected = gpos.filter((gpo) => {
433
+ // Missing SYSVOL path indicates potential orphan
434
+ const hasSysvolPath = gpo.gPCFileSysPath && gpo.gPCFileSysPath.length > 0;
435
+ // Missing version might indicate corruption
436
+ const hasVersion = gpo.versionNumber !== undefined && gpo.versionNumber > 0;
437
+ // Check for obviously broken GPOs
438
+ const hasName = gpo.displayName || gpo.cn;
439
+
440
+ return !hasSysvolPath || !hasVersion || !hasName;
441
+ });
442
+
443
+ return {
444
+ type: 'GPO_ORPHANED',
445
+ severity: 'medium',
446
+ category: 'gpo',
447
+ title: 'Potentially Orphaned GPOs',
448
+ description:
449
+ 'GPOs that may be orphaned (missing SYSVOL content or AD object). ' +
450
+ 'Orphaned GPOs can cause processing errors and may indicate tampering.',
451
+ count: affected.length,
452
+ affectedEntities: includeDetails
453
+ ? affected.map((g) => g.displayName || g.cn || g.dn)
454
+ : undefined,
455
+ details: {
456
+ recommendation:
457
+ 'Compare AD GPOs with SYSVOL folders. Use gpotool.exe or Get-GPO to identify orphans. ' +
458
+ 'Delete orphaned GPOs after verification.',
459
+ },
460
+ };
461
+ }
462
+
463
+ /**
464
+ * Aggregate function: Detect all GPO vulnerabilities
465
+ */
466
+ export function detectGpoVulnerabilities(
467
+ gpos: ADGPO[],
468
+ links: GPOLink[],
469
+ domainPasswordPolicy: { minPasswordLength?: number } | null,
470
+ includeDetails: boolean,
471
+ gpoAcls: GPOAclEntry[] = []
472
+ ): Finding[] {
473
+ return [
474
+ detectGpoDangerousPermissions(gpos, links, includeDetails),
475
+ detectGpoLapsNotDeployed(gpos, links, includeDetails),
476
+ detectGpoWeakPasswordPolicy(gpos, links, domainPasswordPolicy, includeDetails),
477
+ detectGpoUnlinked(gpos, links, includeDetails),
478
+ detectGpoDisabledButLinked(gpos, links, includeDetails),
479
+ detectGpoNoSecurityFiltering(gpos, links, gpoAcls, includeDetails),
480
+ detectGpoAuthenticatedUsersApply(gpos, links, gpoAcls, includeDetails),
481
+ // Phase 4: Advanced GPO detections
482
+ detectGpoPasswordInSysvol(gpos, links, includeDetails),
483
+ detectGpoOrphaned(gpos, links, includeDetails),
484
+ ].filter((finding) => finding.count > 0 || finding.details?.['note']);
485
+ }