@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.
- package/.env.example +60 -0
- package/.env.test.example +33 -0
- package/.github/workflows/ci.yml +83 -0
- package/.github/workflows/release.yml +246 -0
- package/.prettierrc.json +10 -0
- package/CHANGELOG.md +15 -0
- package/Dockerfile +57 -0
- package/LICENSE +190 -0
- package/README.md +194 -0
- package/dist/api/controllers/audit.controller.d.ts +21 -0
- package/dist/api/controllers/audit.controller.d.ts.map +1 -0
- package/dist/api/controllers/audit.controller.js +179 -0
- package/dist/api/controllers/audit.controller.js.map +1 -0
- package/dist/api/controllers/auth.controller.d.ts +16 -0
- package/dist/api/controllers/auth.controller.d.ts.map +1 -0
- package/dist/api/controllers/auth.controller.js +146 -0
- package/dist/api/controllers/auth.controller.js.map +1 -0
- package/dist/api/controllers/export.controller.d.ts +27 -0
- package/dist/api/controllers/export.controller.d.ts.map +1 -0
- package/dist/api/controllers/export.controller.js +80 -0
- package/dist/api/controllers/export.controller.js.map +1 -0
- package/dist/api/controllers/health.controller.d.ts +5 -0
- package/dist/api/controllers/health.controller.d.ts.map +1 -0
- package/dist/api/controllers/health.controller.js +16 -0
- package/dist/api/controllers/health.controller.js.map +1 -0
- package/dist/api/controllers/jobs.controller.d.ts +13 -0
- package/dist/api/controllers/jobs.controller.d.ts.map +1 -0
- package/dist/api/controllers/jobs.controller.js +125 -0
- package/dist/api/controllers/jobs.controller.js.map +1 -0
- package/dist/api/controllers/providers.controller.d.ts +15 -0
- package/dist/api/controllers/providers.controller.d.ts.map +1 -0
- package/dist/api/controllers/providers.controller.js +112 -0
- package/dist/api/controllers/providers.controller.js.map +1 -0
- package/dist/api/dto/AuditRequest.dto.d.ts +6 -0
- package/dist/api/dto/AuditRequest.dto.d.ts.map +1 -0
- package/dist/api/dto/AuditRequest.dto.js +3 -0
- package/dist/api/dto/AuditRequest.dto.js.map +1 -0
- package/dist/api/dto/AuditResponse.dto.d.ts +17 -0
- package/dist/api/dto/AuditResponse.dto.d.ts.map +1 -0
- package/dist/api/dto/AuditResponse.dto.js +3 -0
- package/dist/api/dto/AuditResponse.dto.js.map +1 -0
- package/dist/api/dto/TokenRequest.dto.d.ts +6 -0
- package/dist/api/dto/TokenRequest.dto.d.ts.map +1 -0
- package/dist/api/dto/TokenRequest.dto.js +3 -0
- package/dist/api/dto/TokenRequest.dto.js.map +1 -0
- package/dist/api/dto/TokenResponse.dto.d.ts +12 -0
- package/dist/api/dto/TokenResponse.dto.d.ts.map +1 -0
- package/dist/api/dto/TokenResponse.dto.js +3 -0
- package/dist/api/dto/TokenResponse.dto.js.map +1 -0
- package/dist/api/middlewares/authenticate.d.ts +12 -0
- package/dist/api/middlewares/authenticate.d.ts.map +1 -0
- package/dist/api/middlewares/authenticate.js +141 -0
- package/dist/api/middlewares/authenticate.js.map +1 -0
- package/dist/api/middlewares/errorHandler.d.ts +3 -0
- package/dist/api/middlewares/errorHandler.d.ts.map +1 -0
- package/dist/api/middlewares/errorHandler.js +30 -0
- package/dist/api/middlewares/errorHandler.js.map +1 -0
- package/dist/api/middlewares/rateLimit.d.ts +3 -0
- package/dist/api/middlewares/rateLimit.d.ts.map +1 -0
- package/dist/api/middlewares/rateLimit.js +34 -0
- package/dist/api/middlewares/rateLimit.js.map +1 -0
- package/dist/api/middlewares/validate.d.ts +4 -0
- package/dist/api/middlewares/validate.d.ts.map +1 -0
- package/dist/api/middlewares/validate.js +31 -0
- package/dist/api/middlewares/validate.js.map +1 -0
- package/dist/api/routes/audit.routes.d.ts +5 -0
- package/dist/api/routes/audit.routes.d.ts.map +1 -0
- package/dist/api/routes/audit.routes.js +24 -0
- package/dist/api/routes/audit.routes.js.map +1 -0
- package/dist/api/routes/auth.routes.d.ts +6 -0
- package/dist/api/routes/auth.routes.d.ts.map +1 -0
- package/dist/api/routes/auth.routes.js +22 -0
- package/dist/api/routes/auth.routes.js.map +1 -0
- package/dist/api/routes/export.routes.d.ts +5 -0
- package/dist/api/routes/export.routes.d.ts.map +1 -0
- package/dist/api/routes/export.routes.js +16 -0
- package/dist/api/routes/export.routes.js.map +1 -0
- package/dist/api/routes/health.routes.d.ts +4 -0
- package/dist/api/routes/health.routes.d.ts.map +1 -0
- package/dist/api/routes/health.routes.js +11 -0
- package/dist/api/routes/health.routes.js.map +1 -0
- package/dist/api/routes/index.d.ts +10 -0
- package/dist/api/routes/index.d.ts.map +1 -0
- package/dist/api/routes/index.js +20 -0
- package/dist/api/routes/index.js.map +1 -0
- package/dist/api/routes/providers.routes.d.ts +5 -0
- package/dist/api/routes/providers.routes.d.ts.map +1 -0
- package/dist/api/routes/providers.routes.js +13 -0
- package/dist/api/routes/providers.routes.js.map +1 -0
- package/dist/api/validators/audit.schemas.d.ts +60 -0
- package/dist/api/validators/audit.schemas.d.ts.map +1 -0
- package/dist/api/validators/audit.schemas.js +55 -0
- package/dist/api/validators/audit.schemas.js.map +1 -0
- package/dist/api/validators/auth.schemas.d.ts +17 -0
- package/dist/api/validators/auth.schemas.d.ts.map +1 -0
- package/dist/api/validators/auth.schemas.js +21 -0
- package/dist/api/validators/auth.schemas.js.map +1 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +62 -0
- package/dist/app.js.map +1 -0
- package/dist/config/config.schema.d.ts +65 -0
- package/dist/config/config.schema.d.ts.map +1 -0
- package/dist/config/config.schema.js +95 -0
- package/dist/config/config.schema.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +75 -0
- package/dist/config/index.js.map +1 -0
- package/dist/container.d.ts +47 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +137 -0
- package/dist/container.js.map +1 -0
- package/dist/data/database.d.ts +13 -0
- package/dist/data/database.d.ts.map +1 -0
- package/dist/data/database.js +68 -0
- package/dist/data/database.js.map +1 -0
- package/dist/data/jobs/token-cleanup.job.d.ts +23 -0
- package/dist/data/jobs/token-cleanup.job.d.ts.map +1 -0
- package/dist/data/jobs/token-cleanup.job.js +96 -0
- package/dist/data/jobs/token-cleanup.job.js.map +1 -0
- package/dist/data/migrations/migration.runner.d.ts +13 -0
- package/dist/data/migrations/migration.runner.d.ts.map +1 -0
- package/dist/data/migrations/migration.runner.js +136 -0
- package/dist/data/migrations/migration.runner.js.map +1 -0
- package/dist/data/models/Token.model.d.ts +30 -0
- package/dist/data/models/Token.model.d.ts.map +1 -0
- package/dist/data/models/Token.model.js +3 -0
- package/dist/data/models/Token.model.js.map +1 -0
- package/dist/data/repositories/token.repository.d.ts +16 -0
- package/dist/data/repositories/token.repository.d.ts.map +1 -0
- package/dist/data/repositories/token.repository.js +97 -0
- package/dist/data/repositories/token.repository.js.map +1 -0
- package/dist/providers/azure/auth.provider.d.ts +5 -0
- package/dist/providers/azure/auth.provider.d.ts.map +1 -0
- package/dist/providers/azure/auth.provider.js +13 -0
- package/dist/providers/azure/auth.provider.js.map +1 -0
- package/dist/providers/azure/azure-errors.d.ts +40 -0
- package/dist/providers/azure/azure-errors.d.ts.map +1 -0
- package/dist/providers/azure/azure-errors.js +121 -0
- package/dist/providers/azure/azure-errors.js.map +1 -0
- package/dist/providers/azure/azure-retry.d.ts +41 -0
- package/dist/providers/azure/azure-retry.d.ts.map +1 -0
- package/dist/providers/azure/azure-retry.js +85 -0
- package/dist/providers/azure/azure-retry.js.map +1 -0
- package/dist/providers/azure/graph-client.d.ts +26 -0
- package/dist/providers/azure/graph-client.d.ts.map +1 -0
- package/dist/providers/azure/graph-client.js +146 -0
- package/dist/providers/azure/graph-client.js.map +1 -0
- package/dist/providers/azure/graph.provider.d.ts +23 -0
- package/dist/providers/azure/graph.provider.d.ts.map +1 -0
- package/dist/providers/azure/graph.provider.js +161 -0
- package/dist/providers/azure/graph.provider.js.map +1 -0
- package/dist/providers/azure/queries/app.queries.d.ts +6 -0
- package/dist/providers/azure/queries/app.queries.d.ts.map +1 -0
- package/dist/providers/azure/queries/app.queries.js +9 -0
- package/dist/providers/azure/queries/app.queries.js.map +1 -0
- package/dist/providers/azure/queries/policy.queries.d.ts +6 -0
- package/dist/providers/azure/queries/policy.queries.d.ts.map +1 -0
- package/dist/providers/azure/queries/policy.queries.js +9 -0
- package/dist/providers/azure/queries/policy.queries.js.map +1 -0
- package/dist/providers/azure/queries/user.queries.d.ts +7 -0
- package/dist/providers/azure/queries/user.queries.d.ts.map +1 -0
- package/dist/providers/azure/queries/user.queries.js +10 -0
- package/dist/providers/azure/queries/user.queries.js.map +1 -0
- package/dist/providers/interfaces/IGraphProvider.d.ts +31 -0
- package/dist/providers/interfaces/IGraphProvider.d.ts.map +1 -0
- package/dist/providers/interfaces/IGraphProvider.js +3 -0
- package/dist/providers/interfaces/IGraphProvider.js.map +1 -0
- package/dist/providers/interfaces/ILDAPProvider.d.ts +37 -0
- package/dist/providers/interfaces/ILDAPProvider.d.ts.map +1 -0
- package/dist/providers/interfaces/ILDAPProvider.js +3 -0
- package/dist/providers/interfaces/ILDAPProvider.js.map +1 -0
- package/dist/providers/ldap/acl-parser.d.ts +8 -0
- package/dist/providers/ldap/acl-parser.d.ts.map +1 -0
- package/dist/providers/ldap/acl-parser.js +157 -0
- package/dist/providers/ldap/acl-parser.js.map +1 -0
- package/dist/providers/ldap/ad-mappers.d.ts +8 -0
- package/dist/providers/ldap/ad-mappers.d.ts.map +1 -0
- package/dist/providers/ldap/ad-mappers.js +162 -0
- package/dist/providers/ldap/ad-mappers.js.map +1 -0
- package/dist/providers/ldap/ldap-client.d.ts +33 -0
- package/dist/providers/ldap/ldap-client.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-client.js +195 -0
- package/dist/providers/ldap/ldap-client.js.map +1 -0
- package/dist/providers/ldap/ldap-errors.d.ts +48 -0
- package/dist/providers/ldap/ldap-errors.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-errors.js +120 -0
- package/dist/providers/ldap/ldap-errors.js.map +1 -0
- package/dist/providers/ldap/ldap-retry.d.ts +14 -0
- package/dist/providers/ldap/ldap-retry.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-retry.js +102 -0
- package/dist/providers/ldap/ldap-retry.js.map +1 -0
- package/dist/providers/ldap/ldap-sanitizer.d.ts +12 -0
- package/dist/providers/ldap/ldap-sanitizer.d.ts.map +1 -0
- package/dist/providers/ldap/ldap-sanitizer.js +104 -0
- package/dist/providers/ldap/ldap-sanitizer.js.map +1 -0
- package/dist/providers/ldap/ldap.provider.d.ts +21 -0
- package/dist/providers/ldap/ldap.provider.d.ts.map +1 -0
- package/dist/providers/ldap/ldap.provider.js +165 -0
- package/dist/providers/ldap/ldap.provider.js.map +1 -0
- package/dist/providers/ldap/queries/computer.queries.d.ts +6 -0
- package/dist/providers/ldap/queries/computer.queries.d.ts.map +1 -0
- package/dist/providers/ldap/queries/computer.queries.js +9 -0
- package/dist/providers/ldap/queries/computer.queries.js.map +1 -0
- package/dist/providers/ldap/queries/group.queries.d.ts +6 -0
- package/dist/providers/ldap/queries/group.queries.d.ts.map +1 -0
- package/dist/providers/ldap/queries/group.queries.js +9 -0
- package/dist/providers/ldap/queries/group.queries.js.map +1 -0
- package/dist/providers/ldap/queries/user.queries.d.ts +7 -0
- package/dist/providers/ldap/queries/user.queries.d.ts.map +1 -0
- package/dist/providers/ldap/queries/user.queries.js +10 -0
- package/dist/providers/ldap/queries/user.queries.js.map +1 -0
- package/dist/providers/smb/smb.provider.d.ts +68 -0
- package/dist/providers/smb/smb.provider.d.ts.map +1 -0
- package/dist/providers/smb/smb.provider.js +382 -0
- package/dist/providers/smb/smb.provider.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +44 -0
- package/dist/server.js.map +1 -0
- package/dist/services/audit/ad-audit.service.d.ts +70 -0
- package/dist/services/audit/ad-audit.service.d.ts.map +1 -0
- package/dist/services/audit/ad-audit.service.js +1019 -0
- package/dist/services/audit/ad-audit.service.js.map +1 -0
- package/dist/services/audit/attack-graph.service.d.ts +62 -0
- package/dist/services/audit/attack-graph.service.d.ts.map +1 -0
- package/dist/services/audit/attack-graph.service.js +702 -0
- package/dist/services/audit/attack-graph.service.js.map +1 -0
- package/dist/services/audit/audit.service.d.ts +4 -0
- package/dist/services/audit/audit.service.d.ts.map +1 -0
- package/dist/services/audit/audit.service.js +10 -0
- package/dist/services/audit/audit.service.js.map +1 -0
- package/dist/services/audit/azure-audit.service.d.ts +37 -0
- package/dist/services/audit/azure-audit.service.d.ts.map +1 -0
- package/dist/services/audit/azure-audit.service.js +153 -0
- package/dist/services/audit/azure-audit.service.js.map +1 -0
- package/dist/services/audit/detectors/ad/accounts.detector.d.ts +37 -0
- package/dist/services/audit/detectors/ad/accounts.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/accounts.detector.js +881 -0
- package/dist/services/audit/detectors/ad/accounts.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/adcs.detector.d.ts +21 -0
- package/dist/services/audit/detectors/ad/adcs.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/adcs.detector.js +227 -0
- package/dist/services/audit/detectors/ad/adcs.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/advanced.detector.d.ts +63 -0
- package/dist/services/audit/detectors/ad/advanced.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/advanced.detector.js +867 -0
- package/dist/services/audit/detectors/ad/advanced.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts +16 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.js +369 -0
- package/dist/services/audit/detectors/ad/attack-paths.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/compliance.detector.d.ts +28 -0
- package/dist/services/audit/detectors/ad/compliance.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/compliance.detector.js +896 -0
- package/dist/services/audit/detectors/ad/compliance.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/computers.detector.d.ts +30 -0
- package/dist/services/audit/detectors/ad/computers.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/computers.detector.js +799 -0
- package/dist/services/audit/detectors/ad/computers.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/gpo.detector.d.ts +17 -0
- package/dist/services/audit/detectors/ad/gpo.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/gpo.detector.js +257 -0
- package/dist/services/audit/detectors/ad/gpo.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/groups.detector.d.ts +19 -0
- package/dist/services/audit/detectors/ad/groups.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/groups.detector.js +488 -0
- package/dist/services/audit/detectors/ad/groups.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/index.d.ts +15 -0
- package/dist/services/audit/detectors/ad/index.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/index.js +51 -0
- package/dist/services/audit/detectors/ad/index.js.map +1 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.d.ts +17 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.js +293 -0
- package/dist/services/audit/detectors/ad/kerberos.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.d.ts +23 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.js +328 -0
- package/dist/services/audit/detectors/ad/monitoring.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/network.detector.d.ts +39 -0
- package/dist/services/audit/detectors/ad/network.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/network.detector.js +257 -0
- package/dist/services/audit/detectors/ad/network.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/password.detector.d.ts +14 -0
- package/dist/services/audit/detectors/ad/password.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/password.detector.js +235 -0
- package/dist/services/audit/detectors/ad/password.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/permissions.detector.d.ts +20 -0
- package/dist/services/audit/detectors/ad/permissions.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/permissions.detector.js +392 -0
- package/dist/services/audit/detectors/ad/permissions.detector.js.map +1 -0
- package/dist/services/audit/detectors/ad/trusts.detector.d.ts +11 -0
- package/dist/services/audit/detectors/ad/trusts.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/ad/trusts.detector.js +186 -0
- package/dist/services/audit/detectors/ad/trusts.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/app-security.detector.d.ts +11 -0
- package/dist/services/audit/detectors/azure/app-security.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/app-security.detector.js +184 -0
- package/dist/services/audit/detectors/azure/app-security.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts +10 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.js +130 -0
- package/dist/services/audit/detectors/azure/conditional-access.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts +8 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.js +113 -0
- package/dist/services/audit/detectors/azure/privilege-security.detector.js.map +1 -0
- package/dist/services/audit/detectors/azure/user-security.detector.d.ts +14 -0
- package/dist/services/audit/detectors/azure/user-security.detector.d.ts.map +1 -0
- package/dist/services/audit/detectors/azure/user-security.detector.js +198 -0
- package/dist/services/audit/detectors/azure/user-security.detector.js.map +1 -0
- package/dist/services/audit/detectors/index.d.ts +2 -0
- package/dist/services/audit/detectors/index.d.ts.map +1 -0
- package/dist/services/audit/detectors/index.js +38 -0
- package/dist/services/audit/detectors/index.js.map +1 -0
- package/dist/services/audit/response-formatter.d.ts +176 -0
- package/dist/services/audit/response-formatter.d.ts.map +1 -0
- package/dist/services/audit/response-formatter.js +240 -0
- package/dist/services/audit/response-formatter.js.map +1 -0
- package/dist/services/audit/scoring.service.d.ts +15 -0
- package/dist/services/audit/scoring.service.d.ts.map +1 -0
- package/dist/services/audit/scoring.service.js +139 -0
- package/dist/services/audit/scoring.service.js.map +1 -0
- package/dist/services/auth/crypto.service.d.ts +19 -0
- package/dist/services/auth/crypto.service.d.ts.map +1 -0
- package/dist/services/auth/crypto.service.js +135 -0
- package/dist/services/auth/crypto.service.js.map +1 -0
- package/dist/services/auth/errors.d.ts +19 -0
- package/dist/services/auth/errors.d.ts.map +1 -0
- package/dist/services/auth/errors.js +46 -0
- package/dist/services/auth/errors.js.map +1 -0
- package/dist/services/auth/token.service.d.ts +41 -0
- package/dist/services/auth/token.service.d.ts.map +1 -0
- package/dist/services/auth/token.service.js +208 -0
- package/dist/services/auth/token.service.js.map +1 -0
- package/dist/services/config/config.service.d.ts +6 -0
- package/dist/services/config/config.service.d.ts.map +1 -0
- package/dist/services/config/config.service.js +64 -0
- package/dist/services/config/config.service.js.map +1 -0
- package/dist/services/export/export.service.d.ts +28 -0
- package/dist/services/export/export.service.d.ts.map +1 -0
- package/dist/services/export/export.service.js +28 -0
- package/dist/services/export/export.service.js.map +1 -0
- package/dist/services/export/formatters/csv.formatter.d.ts +8 -0
- package/dist/services/export/formatters/csv.formatter.d.ts.map +1 -0
- package/dist/services/export/formatters/csv.formatter.js +46 -0
- package/dist/services/export/formatters/csv.formatter.js.map +1 -0
- package/dist/services/export/formatters/json.formatter.d.ts +40 -0
- package/dist/services/export/formatters/json.formatter.d.ts.map +1 -0
- package/dist/services/export/formatters/json.formatter.js +58 -0
- package/dist/services/export/formatters/json.formatter.js.map +1 -0
- package/dist/services/jobs/azure-job-runner.d.ts +38 -0
- package/dist/services/jobs/azure-job-runner.d.ts.map +1 -0
- package/dist/services/jobs/azure-job-runner.js +199 -0
- package/dist/services/jobs/azure-job-runner.js.map +1 -0
- package/dist/services/jobs/index.d.ts +4 -0
- package/dist/services/jobs/index.d.ts.map +1 -0
- package/dist/services/jobs/index.js +20 -0
- package/dist/services/jobs/index.js.map +1 -0
- package/dist/services/jobs/job-runner.d.ts +64 -0
- package/dist/services/jobs/job-runner.d.ts.map +1 -0
- package/dist/services/jobs/job-runner.js +952 -0
- package/dist/services/jobs/job-runner.js.map +1 -0
- package/dist/services/jobs/job-store.d.ts +27 -0
- package/dist/services/jobs/job-store.d.ts.map +1 -0
- package/dist/services/jobs/job-store.js +261 -0
- package/dist/services/jobs/job-store.js.map +1 -0
- package/dist/services/jobs/job.types.d.ts +67 -0
- package/dist/services/jobs/job.types.d.ts.map +1 -0
- package/dist/services/jobs/job.types.js +36 -0
- package/dist/services/jobs/job.types.js.map +1 -0
- package/dist/types/ad.types.d.ts +74 -0
- package/dist/types/ad.types.d.ts.map +1 -0
- package/dist/types/ad.types.js +3 -0
- package/dist/types/ad.types.js.map +1 -0
- package/dist/types/adcs.types.d.ts +58 -0
- package/dist/types/adcs.types.d.ts.map +1 -0
- package/dist/types/adcs.types.js +38 -0
- package/dist/types/adcs.types.js.map +1 -0
- package/dist/types/attack-graph.types.d.ts +135 -0
- package/dist/types/attack-graph.types.d.ts.map +1 -0
- package/dist/types/attack-graph.types.js +58 -0
- package/dist/types/attack-graph.types.js.map +1 -0
- package/dist/types/audit.types.d.ts +34 -0
- package/dist/types/audit.types.d.ts.map +1 -0
- package/dist/types/audit.types.js +3 -0
- package/dist/types/audit.types.js.map +1 -0
- package/dist/types/azure.types.d.ts +61 -0
- package/dist/types/azure.types.d.ts.map +1 -0
- package/dist/types/azure.types.js +3 -0
- package/dist/types/azure.types.js.map +1 -0
- package/dist/types/config.types.d.ts +63 -0
- package/dist/types/config.types.d.ts.map +1 -0
- package/dist/types/config.types.js +3 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/error.types.d.ts +33 -0
- package/dist/types/error.types.d.ts.map +1 -0
- package/dist/types/error.types.js +70 -0
- package/dist/types/error.types.js.map +1 -0
- package/dist/types/finding.types.d.ts +133 -0
- package/dist/types/finding.types.d.ts.map +1 -0
- package/dist/types/finding.types.js +3 -0
- package/dist/types/finding.types.js.map +1 -0
- package/dist/types/gpo.types.d.ts +39 -0
- package/dist/types/gpo.types.d.ts.map +1 -0
- package/dist/types/gpo.types.js +15 -0
- package/dist/types/gpo.types.js.map +1 -0
- package/dist/types/token.types.d.ts +26 -0
- package/dist/types/token.types.d.ts.map +1 -0
- package/dist/types/token.types.js +3 -0
- package/dist/types/token.types.js.map +1 -0
- package/dist/types/trust.types.d.ts +45 -0
- package/dist/types/trust.types.d.ts.map +1 -0
- package/dist/types/trust.types.js +71 -0
- package/dist/types/trust.types.js.map +1 -0
- package/dist/utils/entity-converter.d.ts +17 -0
- package/dist/utils/entity-converter.d.ts.map +1 -0
- package/dist/utils/entity-converter.js +285 -0
- package/dist/utils/entity-converter.js.map +1 -0
- package/dist/utils/graph.util.d.ts +66 -0
- package/dist/utils/graph.util.d.ts.map +1 -0
- package/dist/utils/graph.util.js +382 -0
- package/dist/utils/graph.util.js.map +1 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +86 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/type-name-normalizer.d.ts +5 -0
- package/dist/utils/type-name-normalizer.d.ts.map +1 -0
- package/dist/utils/type-name-normalizer.js +218 -0
- package/dist/utils/type-name-normalizer.js.map +1 -0
- package/docker-compose.yml +26 -0
- package/docs/api/README.md +178 -0
- package/docs/api/openapi.yaml +1524 -0
- package/eslint.config.js +54 -0
- package/jest.config.js +38 -0
- package/package.json +97 -0
- package/scripts/fetch-ad-cert.sh +142 -0
- package/src/.gitkeep +0 -0
- package/src/api/.gitkeep +0 -0
- package/src/api/controllers/.gitkeep +0 -0
- package/src/api/controllers/audit.controller.ts +313 -0
- package/src/api/controllers/auth.controller.ts +258 -0
- package/src/api/controllers/export.controller.ts +153 -0
- package/src/api/controllers/health.controller.ts +16 -0
- package/src/api/controllers/jobs.controller.ts +187 -0
- package/src/api/controllers/providers.controller.ts +165 -0
- package/src/api/dto/.gitkeep +0 -0
- package/src/api/dto/AuditRequest.dto.ts +8 -0
- package/src/api/dto/AuditResponse.dto.ts +19 -0
- package/src/api/dto/TokenRequest.dto.ts +8 -0
- package/src/api/dto/TokenResponse.dto.ts +14 -0
- package/src/api/middlewares/.gitkeep +0 -0
- package/src/api/middlewares/authenticate.ts +203 -0
- package/src/api/middlewares/errorHandler.ts +54 -0
- package/src/api/middlewares/rateLimit.ts +35 -0
- package/src/api/middlewares/validate.ts +32 -0
- package/src/api/routes/.gitkeep +0 -0
- package/src/api/routes/audit.routes.ts +77 -0
- package/src/api/routes/auth.routes.ts +71 -0
- package/src/api/routes/export.routes.ts +34 -0
- package/src/api/routes/health.routes.ts +14 -0
- package/src/api/routes/index.ts +40 -0
- package/src/api/routes/providers.routes.ts +24 -0
- package/src/api/validators/.gitkeep +0 -0
- package/src/api/validators/audit.schemas.ts +59 -0
- package/src/api/validators/auth.schemas.ts +59 -0
- package/src/app.ts +87 -0
- package/src/config/.gitkeep +0 -0
- package/src/config/config.schema.ts +108 -0
- package/src/config/index.ts +82 -0
- package/src/container.ts +221 -0
- package/src/data/.gitkeep +0 -0
- package/src/data/database.ts +78 -0
- package/src/data/jobs/token-cleanup.job.ts +166 -0
- package/src/data/migrations/.gitkeep +0 -0
- package/src/data/migrations/001_initial_schema.sql +47 -0
- package/src/data/migrations/migration.runner.ts +125 -0
- package/src/data/models/.gitkeep +0 -0
- package/src/data/models/Token.model.ts +35 -0
- package/src/data/repositories/.gitkeep +0 -0
- package/src/data/repositories/token.repository.ts +160 -0
- package/src/providers/.gitkeep +0 -0
- package/src/providers/azure/.gitkeep +0 -0
- package/src/providers/azure/auth.provider.ts +14 -0
- package/src/providers/azure/azure-errors.ts +189 -0
- package/src/providers/azure/azure-retry.ts +168 -0
- package/src/providers/azure/graph-client.ts +315 -0
- package/src/providers/azure/graph.provider.ts +294 -0
- package/src/providers/azure/queries/app.queries.ts +9 -0
- package/src/providers/azure/queries/policy.queries.ts +9 -0
- package/src/providers/azure/queries/user.queries.ts +10 -0
- package/src/providers/interfaces/.gitkeep +0 -0
- package/src/providers/interfaces/IGraphProvider.ts +117 -0
- package/src/providers/interfaces/ILDAPProvider.ts +142 -0
- package/src/providers/ldap/.gitkeep +0 -0
- package/src/providers/ldap/acl-parser.ts +231 -0
- package/src/providers/ldap/ad-mappers.ts +280 -0
- package/src/providers/ldap/ldap-client.ts +259 -0
- package/src/providers/ldap/ldap-errors.ts +188 -0
- package/src/providers/ldap/ldap-retry.ts +267 -0
- package/src/providers/ldap/ldap-sanitizer.ts +273 -0
- package/src/providers/ldap/ldap.provider.ts +293 -0
- package/src/providers/ldap/queries/computer.queries.ts +9 -0
- package/src/providers/ldap/queries/group.queries.ts +9 -0
- package/src/providers/ldap/queries/user.queries.ts +10 -0
- package/src/providers/smb/smb.provider.ts +653 -0
- package/src/server.ts +60 -0
- package/src/services/.gitkeep +0 -0
- package/src/services/audit/.gitkeep +0 -0
- package/src/services/audit/ad-audit.service.ts +1481 -0
- package/src/services/audit/attack-graph.service.ts +1104 -0
- package/src/services/audit/audit.service.ts +12 -0
- package/src/services/audit/azure-audit.service.ts +286 -0
- package/src/services/audit/detectors/ad/accounts.detector.ts +1232 -0
- package/src/services/audit/detectors/ad/adcs.detector.ts +449 -0
- package/src/services/audit/detectors/ad/advanced.detector.ts +1270 -0
- package/src/services/audit/detectors/ad/attack-paths.detector.ts +600 -0
- package/src/services/audit/detectors/ad/compliance.detector.ts +1421 -0
- package/src/services/audit/detectors/ad/computers.detector.ts +1188 -0
- package/src/services/audit/detectors/ad/gpo.detector.ts +485 -0
- package/src/services/audit/detectors/ad/groups.detector.ts +685 -0
- package/src/services/audit/detectors/ad/index.ts +84 -0
- package/src/services/audit/detectors/ad/kerberos.detector.ts +424 -0
- package/src/services/audit/detectors/ad/monitoring.detector.ts +501 -0
- package/src/services/audit/detectors/ad/network.detector.ts +538 -0
- package/src/services/audit/detectors/ad/password.detector.ts +324 -0
- package/src/services/audit/detectors/ad/permissions.detector.ts +637 -0
- package/src/services/audit/detectors/ad/trusts.detector.ts +315 -0
- package/src/services/audit/detectors/azure/app-security.detector.ts +246 -0
- package/src/services/audit/detectors/azure/conditional-access.detector.ts +186 -0
- package/src/services/audit/detectors/azure/privilege-security.detector.ts +176 -0
- package/src/services/audit/detectors/azure/user-security.detector.ts +280 -0
- package/src/services/audit/detectors/index.ts +18 -0
- package/src/services/audit/response-formatter.ts +604 -0
- package/src/services/audit/scoring.service.ts +234 -0
- package/src/services/auth/.gitkeep +0 -0
- package/src/services/auth/crypto.service.ts +230 -0
- package/src/services/auth/errors.ts +47 -0
- package/src/services/auth/token.service.ts +420 -0
- package/src/services/config/.gitkeep +0 -0
- package/src/services/config/config.service.ts +75 -0
- package/src/services/export/.gitkeep +0 -0
- package/src/services/export/export.service.ts +99 -0
- package/src/services/export/formatters/csv.formatter.ts +124 -0
- package/src/services/export/formatters/json.formatter.ts +160 -0
- package/src/services/jobs/azure-job-runner.ts +312 -0
- package/src/services/jobs/index.ts +9 -0
- package/src/services/jobs/job-runner.ts +1280 -0
- package/src/services/jobs/job-store.ts +384 -0
- package/src/services/jobs/job.types.ts +182 -0
- package/src/types/.gitkeep +0 -0
- package/src/types/ad.types.ts +91 -0
- package/src/types/adcs.types.ts +107 -0
- package/src/types/attack-graph.types.ts +260 -0
- package/src/types/audit.types.ts +42 -0
- package/src/types/azure.types.ts +68 -0
- package/src/types/config.types.ts +79 -0
- package/src/types/error.types.ts +69 -0
- package/src/types/finding.types.ts +284 -0
- package/src/types/gpo.types.ts +72 -0
- package/src/types/smb2.d.ts +73 -0
- package/src/types/token.types.ts +32 -0
- package/src/types/trust.types.ts +140 -0
- package/src/utils/.gitkeep +0 -0
- package/src/utils/entity-converter.ts +453 -0
- package/src/utils/graph.util.ts +609 -0
- package/src/utils/logger.ts +111 -0
- package/src/utils/type-name-normalizer.ts +302 -0
- package/tests/.gitkeep +0 -0
- package/tests/e2e/.gitkeep +0 -0
- package/tests/fixtures/.gitkeep +0 -0
- package/tests/integration/.gitkeep +0 -0
- package/tests/integration/README.md +156 -0
- package/tests/integration/ad-audit.integration.test.ts +216 -0
- package/tests/integration/api/.gitkeep +0 -0
- package/tests/integration/api/endpoints.integration.test.ts +431 -0
- package/tests/integration/auth/jwt-authentication.integration.test.ts +358 -0
- package/tests/integration/providers/.gitkeep +0 -0
- package/tests/integration/providers/azure-basic.integration.test.ts +167 -0
- package/tests/integration/providers/ldap-basic.integration.test.ts +152 -0
- package/tests/integration/providers/ldap-connectivity.test.ts +44 -0
- package/tests/integration/providers/ldap-provider.integration.test.ts +347 -0
- package/tests/mocks/.gitkeep +0 -0
- package/tests/setup.ts +16 -0
- package/tests/unit/.gitkeep +0 -0
- package/tests/unit/api/middlewares/authenticate.test.ts +446 -0
- package/tests/unit/providers/.gitkeep +0 -0
- package/tests/unit/providers/azure/azure-errors.test.ts +193 -0
- package/tests/unit/providers/azure/azure-retry.test.ts +254 -0
- package/tests/unit/providers/azure/graph-provider.test.ts +313 -0
- package/tests/unit/providers/ldap/ad-mappers.test.ts +392 -0
- package/tests/unit/providers/ldap/ldap-provider.test.ts +376 -0
- package/tests/unit/providers/ldap/ldap-retry.test.ts +377 -0
- package/tests/unit/providers/ldap/ldap-sanitizer.test.ts +301 -0
- package/tests/unit/sample.test.ts +19 -0
- package/tests/unit/services/.gitkeep +0 -0
- package/tests/unit/services/audit/detectors/ad/accounts.detector.test.ts +393 -0
- package/tests/unit/services/audit/detectors/ad/advanced.detector.test.ts +380 -0
- package/tests/unit/services/audit/detectors/ad/computers.detector.test.ts +440 -0
- package/tests/unit/services/audit/detectors/ad/groups.detector.test.ts +276 -0
- package/tests/unit/services/audit/detectors/ad/kerberos.detector.test.ts +215 -0
- package/tests/unit/services/audit/detectors/ad/password.detector.test.ts +226 -0
- package/tests/unit/services/audit/detectors/ad/permissions.detector.test.ts +244 -0
- package/tests/unit/services/audit/detectors/azure/app-security.detector.test.ts +349 -0
- package/tests/unit/services/audit/detectors/azure/conditional-access.detector.test.ts +374 -0
- package/tests/unit/services/audit/detectors/azure/privilege-security.detector.test.ts +374 -0
- package/tests/unit/services/audit/detectors/azure/user-security.detector.test.ts +297 -0
- package/tests/unit/services/auth/crypto.service.test.ts +296 -0
- package/tests/unit/services/auth/token.service.test.ts +579 -0
- package/tests/unit/services/export/export.service.test.ts +241 -0
- package/tests/unit/services/export/formatters/csv.formatter.test.ts +270 -0
- package/tests/unit/services/export/formatters/json.formatter.test.ts +258 -0
- package/tests/unit/utils/.gitkeep +0 -0
- package/tsconfig.json +50 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain Trusts Security Vulnerability Detector
|
|
3
|
+
*
|
|
4
|
+
* Analyzes trust relationships for security risks.
|
|
5
|
+
*
|
|
6
|
+
* Vulnerabilities detected (7):
|
|
7
|
+
* HIGH (4):
|
|
8
|
+
* - TRUST_SID_FILTERING_DISABLED: SID history attacks possible
|
|
9
|
+
* - TRUST_EXTERNAL_NO_SELECTIVE_AUTH: External trust without selective authentication
|
|
10
|
+
* - TRUST_AES_DISABLED: AES encryption not supported on trust
|
|
11
|
+
* - TRUST_RC4_ONLY: Trust only supports weak RC4 encryption
|
|
12
|
+
*
|
|
13
|
+
* MEDIUM (3):
|
|
14
|
+
* - TRUST_BIDIRECTIONAL: Two-way trust enables lateral movement
|
|
15
|
+
* - TRUST_FOREST_TRANSITIVE: Transitive forest trust increases attack surface
|
|
16
|
+
* - TRUST_INACTIVE: Trust relationship not modified in 180+ days
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { Finding } from '../../../../types/finding.types';
|
|
20
|
+
import {
|
|
21
|
+
ADTrustExtended,
|
|
22
|
+
TRUST_ATTRIBUTE_QUARANTINED_DOMAIN,
|
|
23
|
+
TRUST_ATTRIBUTE_CROSS_ORGANIZATION,
|
|
24
|
+
TRUST_ATTRIBUTE_FOREST_TRANSITIVE,
|
|
25
|
+
TRUST_ATTRIBUTE_WITHIN_FOREST,
|
|
26
|
+
TRUST_DIRECTION_BIDIRECTIONAL,
|
|
27
|
+
} from '../../../../types/trust.types';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* TRUST_SID_FILTERING_DISABLED: SID filtering not enabled
|
|
31
|
+
* Allows SID history injection attacks across trust boundary
|
|
32
|
+
*/
|
|
33
|
+
export function detectTrustSidFilteringDisabled(
|
|
34
|
+
trusts: ADTrustExtended[],
|
|
35
|
+
includeDetails: boolean
|
|
36
|
+
): Finding {
|
|
37
|
+
// SID filtering should be enabled (TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
|
|
38
|
+
// except for trusts within the same forest
|
|
39
|
+
const affected = trusts.filter((t) => {
|
|
40
|
+
// Skip intra-forest trusts (parent-child) - SID filtering not applicable
|
|
41
|
+
if ((t.trustAttributes & TRUST_ATTRIBUTE_WITHIN_FOREST) !== 0) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Check if SID filtering is disabled (QUARANTINED_DOMAIN flag NOT set)
|
|
46
|
+
const sidFilteringDisabled = (t.trustAttributes & TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) === 0;
|
|
47
|
+
|
|
48
|
+
return sidFilteringDisabled;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
type: 'TRUST_SID_FILTERING_DISABLED',
|
|
53
|
+
severity: 'high',
|
|
54
|
+
category: 'trusts',
|
|
55
|
+
title: 'SID Filtering Disabled on Trust',
|
|
56
|
+
description:
|
|
57
|
+
'Trust relationships without SID filtering allow SID history injection attacks, enabling attackers to impersonate any user in the trusted domain.',
|
|
58
|
+
count: affected.length,
|
|
59
|
+
affectedEntities: includeDetails ? affected.map((t) => t.name) : undefined,
|
|
60
|
+
details:
|
|
61
|
+
affected.length > 0
|
|
62
|
+
? {
|
|
63
|
+
recommendation: 'Enable SID filtering (quarantine) on external and forest trusts.',
|
|
64
|
+
}
|
|
65
|
+
: undefined,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* TRUST_EXTERNAL_NO_SELECTIVE_AUTH: External trust without selective authentication
|
|
71
|
+
* All users from trusted domain can authenticate to any resource
|
|
72
|
+
*/
|
|
73
|
+
export function detectTrustExternalNoSelectiveAuth(
|
|
74
|
+
trusts: ADTrustExtended[],
|
|
75
|
+
includeDetails: boolean
|
|
76
|
+
): Finding {
|
|
77
|
+
// Selective authentication should be enabled for external trusts
|
|
78
|
+
// to limit which users can authenticate
|
|
79
|
+
const affected = trusts.filter((t) => {
|
|
80
|
+
// Only check external trusts (not forest or intra-forest)
|
|
81
|
+
const isExternal =
|
|
82
|
+
(t.trustAttributes & TRUST_ATTRIBUTE_FOREST_TRANSITIVE) === 0 &&
|
|
83
|
+
(t.trustAttributes & TRUST_ATTRIBUTE_WITHIN_FOREST) === 0;
|
|
84
|
+
|
|
85
|
+
if (!isExternal) return false;
|
|
86
|
+
|
|
87
|
+
// Check if selective authentication is disabled
|
|
88
|
+
const selectiveAuthDisabled = (t.trustAttributes & TRUST_ATTRIBUTE_CROSS_ORGANIZATION) === 0;
|
|
89
|
+
|
|
90
|
+
return selectiveAuthDisabled;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
type: 'TRUST_EXTERNAL_NO_SELECTIVE_AUTH',
|
|
95
|
+
severity: 'high',
|
|
96
|
+
category: 'trusts',
|
|
97
|
+
title: 'External Trust Without Selective Authentication',
|
|
98
|
+
description:
|
|
99
|
+
'External trust without selective authentication allows any user from the trusted domain to authenticate to any resource in this domain.',
|
|
100
|
+
count: affected.length,
|
|
101
|
+
affectedEntities: includeDetails ? affected.map((t) => t.name) : undefined,
|
|
102
|
+
details:
|
|
103
|
+
affected.length > 0
|
|
104
|
+
? {
|
|
105
|
+
recommendation:
|
|
106
|
+
'Enable selective authentication and explicitly grant access only to required resources.',
|
|
107
|
+
}
|
|
108
|
+
: undefined,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* TRUST_BIDIRECTIONAL: Two-way trust relationship
|
|
114
|
+
* Increases attack surface - compromise in either domain affects both
|
|
115
|
+
*/
|
|
116
|
+
export function detectTrustBidirectional(
|
|
117
|
+
trusts: ADTrustExtended[],
|
|
118
|
+
includeDetails: boolean
|
|
119
|
+
): Finding {
|
|
120
|
+
const affected = trusts.filter((t) => {
|
|
121
|
+
// Skip intra-forest trusts (parent-child are always bidirectional by design)
|
|
122
|
+
if ((t.trustAttributes & TRUST_ATTRIBUTE_WITHIN_FOREST) !== 0) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return t.trustDirection === TRUST_DIRECTION_BIDIRECTIONAL;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
type: 'TRUST_BIDIRECTIONAL',
|
|
131
|
+
severity: 'medium',
|
|
132
|
+
category: 'trusts',
|
|
133
|
+
title: 'Bidirectional Trust Relationship',
|
|
134
|
+
description:
|
|
135
|
+
'Two-way trust allows authentication in both directions, increasing the attack surface. A compromise in either domain can lead to lateral movement to the other.',
|
|
136
|
+
count: affected.length,
|
|
137
|
+
affectedEntities: includeDetails ? affected.map((t) => t.name) : undefined,
|
|
138
|
+
details:
|
|
139
|
+
affected.length > 0
|
|
140
|
+
? {
|
|
141
|
+
recommendation:
|
|
142
|
+
'Consider using one-way trusts where possible. Implement selective authentication.',
|
|
143
|
+
}
|
|
144
|
+
: undefined,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* TRUST_FOREST_TRANSITIVE: Transitive forest trust
|
|
150
|
+
* Trust extends to all domains in the trusted forest
|
|
151
|
+
*/
|
|
152
|
+
export function detectTrustForestTransitive(
|
|
153
|
+
trusts: ADTrustExtended[],
|
|
154
|
+
includeDetails: boolean
|
|
155
|
+
): Finding {
|
|
156
|
+
const affected = trusts.filter((t) => {
|
|
157
|
+
return (t.trustAttributes & TRUST_ATTRIBUTE_FOREST_TRANSITIVE) !== 0;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
type: 'TRUST_FOREST_TRANSITIVE',
|
|
162
|
+
severity: 'medium',
|
|
163
|
+
category: 'trusts',
|
|
164
|
+
title: 'Transitive Forest Trust',
|
|
165
|
+
description:
|
|
166
|
+
'Forest trust is transitive, meaning all domains in the trusted forest can access this domain. This significantly increases the trust boundary.',
|
|
167
|
+
count: affected.length,
|
|
168
|
+
affectedEntities: includeDetails ? affected.map((t) => t.name) : undefined,
|
|
169
|
+
details:
|
|
170
|
+
affected.length > 0
|
|
171
|
+
? {
|
|
172
|
+
recommendation:
|
|
173
|
+
'Review necessity of forest trust. Consider selective authentication and SID filtering.',
|
|
174
|
+
}
|
|
175
|
+
: undefined,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Encryption type bit flags from msDS-SupportedEncryptionTypes
|
|
180
|
+
const ENC_TYPE_DES_CBC_CRC = 0x1;
|
|
181
|
+
const ENC_TYPE_DES_CBC_MD5 = 0x2;
|
|
182
|
+
const ENC_TYPE_RC4_HMAC = 0x4;
|
|
183
|
+
const ENC_TYPE_AES128 = 0x8;
|
|
184
|
+
const ENC_TYPE_AES256 = 0x10;
|
|
185
|
+
const ENC_WEAK_ONLY = ENC_TYPE_DES_CBC_CRC | ENC_TYPE_DES_CBC_MD5 | ENC_TYPE_RC4_HMAC;
|
|
186
|
+
const ENC_AES_TYPES = ENC_TYPE_AES128 | ENC_TYPE_AES256;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* TRUST_AES_DISABLED: AES encryption not enabled on trust
|
|
190
|
+
* Forces use of weaker encryption algorithms
|
|
191
|
+
*/
|
|
192
|
+
export function detectTrustAesDisabled(
|
|
193
|
+
trusts: ADTrustExtended[],
|
|
194
|
+
includeDetails: boolean
|
|
195
|
+
): Finding {
|
|
196
|
+
const affected = trusts.filter((t) => {
|
|
197
|
+
// Skip if encryption types not available
|
|
198
|
+
if (t.supportedEncryptionTypes === undefined) return false;
|
|
199
|
+
// Check if AES is NOT supported (neither AES128 nor AES256)
|
|
200
|
+
return (t.supportedEncryptionTypes & ENC_AES_TYPES) === 0;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
type: 'TRUST_AES_DISABLED',
|
|
205
|
+
severity: 'high',
|
|
206
|
+
category: 'trusts',
|
|
207
|
+
title: 'AES Encryption Disabled on Trust',
|
|
208
|
+
description:
|
|
209
|
+
'Trust relationship does not support AES encryption. This forces the use of weaker encryption algorithms (RC4/DES) which are more vulnerable to offline cracking.',
|
|
210
|
+
count: affected.length,
|
|
211
|
+
affectedEntities: includeDetails ? affected.map((t) => t.name) : undefined,
|
|
212
|
+
details:
|
|
213
|
+
affected.length > 0
|
|
214
|
+
? {
|
|
215
|
+
recommendation:
|
|
216
|
+
'Enable AES128 and AES256 encryption on trust relationship. Ensure both domains support AES.',
|
|
217
|
+
}
|
|
218
|
+
: undefined,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* TRUST_RC4_ONLY: Trust only supports RC4 encryption
|
|
224
|
+
* RC4 is deprecated and vulnerable to offline attacks
|
|
225
|
+
*/
|
|
226
|
+
export function detectTrustRc4Only(
|
|
227
|
+
trusts: ADTrustExtended[],
|
|
228
|
+
includeDetails: boolean
|
|
229
|
+
): Finding {
|
|
230
|
+
const affected = trusts.filter((t) => {
|
|
231
|
+
// Skip if encryption types not available
|
|
232
|
+
if (t.supportedEncryptionTypes === undefined) return false;
|
|
233
|
+
// Check if ONLY weak encryption is supported (RC4/DES only, no AES)
|
|
234
|
+
const hasOnlyWeak =
|
|
235
|
+
(t.supportedEncryptionTypes & ENC_WEAK_ONLY) !== 0 &&
|
|
236
|
+
(t.supportedEncryptionTypes & ENC_AES_TYPES) === 0;
|
|
237
|
+
// Specifically RC4 only (not DES)
|
|
238
|
+
const isRc4Only =
|
|
239
|
+
hasOnlyWeak && (t.supportedEncryptionTypes & ENC_TYPE_RC4_HMAC) !== 0;
|
|
240
|
+
return isRc4Only;
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
type: 'TRUST_RC4_ONLY',
|
|
245
|
+
severity: 'high',
|
|
246
|
+
category: 'trusts',
|
|
247
|
+
title: 'Trust Only Supports RC4 Encryption',
|
|
248
|
+
description:
|
|
249
|
+
'Trust relationship only supports RC4 encryption (no AES). RC4 is deprecated and Kerberos tickets encrypted with RC4 are vulnerable to offline cracking attacks.',
|
|
250
|
+
count: affected.length,
|
|
251
|
+
affectedEntities: includeDetails ? affected.map((t) => t.name) : undefined,
|
|
252
|
+
details:
|
|
253
|
+
affected.length > 0
|
|
254
|
+
? {
|
|
255
|
+
recommendation:
|
|
256
|
+
'Enable AES encryption on trust. If the partner domain does not support AES, plan an upgrade path.',
|
|
257
|
+
}
|
|
258
|
+
: undefined,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* TRUST_INACTIVE: Trust not modified in 180+ days
|
|
264
|
+
* May indicate abandoned or forgotten trust relationships
|
|
265
|
+
*/
|
|
266
|
+
export function detectTrustInactive(
|
|
267
|
+
trusts: ADTrustExtended[],
|
|
268
|
+
includeDetails: boolean
|
|
269
|
+
): Finding {
|
|
270
|
+
const now = Date.now();
|
|
271
|
+
const sixMonthsAgo = now - 180 * 24 * 60 * 60 * 1000;
|
|
272
|
+
|
|
273
|
+
const affected = trusts.filter((t) => {
|
|
274
|
+
// Skip if whenChanged not available
|
|
275
|
+
if (!t.whenChanged) return false;
|
|
276
|
+
// Check if trust hasn't been modified in 180+ days
|
|
277
|
+
return t.whenChanged.getTime() < sixMonthsAgo;
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
return {
|
|
281
|
+
type: 'TRUST_INACTIVE',
|
|
282
|
+
severity: 'medium',
|
|
283
|
+
category: 'trusts',
|
|
284
|
+
title: 'Inactive Trust Relationship',
|
|
285
|
+
description:
|
|
286
|
+
'Trust relationship has not been modified in over 180 days. May indicate an abandoned or forgotten trust that should be reviewed for necessity.',
|
|
287
|
+
count: affected.length,
|
|
288
|
+
affectedEntities: includeDetails ? affected.map((t) => t.name) : undefined,
|
|
289
|
+
details:
|
|
290
|
+
affected.length > 0
|
|
291
|
+
? {
|
|
292
|
+
recommendation:
|
|
293
|
+
'Review necessity of inactive trusts. Remove trusts that are no longer needed to reduce attack surface.',
|
|
294
|
+
}
|
|
295
|
+
: undefined,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Aggregate function: Detect all trust vulnerabilities
|
|
301
|
+
*/
|
|
302
|
+
export function detectTrustVulnerabilities(
|
|
303
|
+
trusts: ADTrustExtended[],
|
|
304
|
+
includeDetails: boolean
|
|
305
|
+
): Finding[] {
|
|
306
|
+
return [
|
|
307
|
+
detectTrustSidFilteringDisabled(trusts, includeDetails),
|
|
308
|
+
detectTrustExternalNoSelectiveAuth(trusts, includeDetails),
|
|
309
|
+
detectTrustBidirectional(trusts, includeDetails),
|
|
310
|
+
detectTrustForestTransitive(trusts, includeDetails),
|
|
311
|
+
detectTrustAesDisabled(trusts, includeDetails),
|
|
312
|
+
detectTrustRc4Only(trusts, includeDetails),
|
|
313
|
+
detectTrustInactive(trusts, includeDetails),
|
|
314
|
+
].filter((finding) => finding.count > 0);
|
|
315
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App Security Vulnerability Detector for Azure AD
|
|
3
|
+
*
|
|
4
|
+
* Detects application and service principal vulnerabilities in Azure AD/Entra ID.
|
|
5
|
+
* Story 1.8: Azure Vulnerability Detection Engine
|
|
6
|
+
*
|
|
7
|
+
* Vulnerabilities detected (7):
|
|
8
|
+
* CRITICAL (1):
|
|
9
|
+
* - AZURE_APP_EXCESSIVE_GRAPH_PERMS
|
|
10
|
+
*
|
|
11
|
+
* HIGH (3):
|
|
12
|
+
* - AZURE_APP_CREDENTIAL_EXPIRED
|
|
13
|
+
* - AZURE_APP_LONG_LIVED_CREDS
|
|
14
|
+
* - AZURE_APP_MULTITENANT_UNVERIFIED
|
|
15
|
+
*
|
|
16
|
+
* MEDIUM (3):
|
|
17
|
+
* - AZURE_APP_CREDENTIAL_EXPIRING
|
|
18
|
+
* - AZURE_SP_DISABLED_WITH_CREDS
|
|
19
|
+
* - AZURE_APP_NO_OWNER
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { AzureApp } from '../../../../types/azure.types';
|
|
23
|
+
import { Finding } from '../../../../types/finding.types';
|
|
24
|
+
import { toAffectedAppEntities } from '../../../../utils/entity-converter';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Check for applications with excessive Microsoft Graph permissions
|
|
28
|
+
*/
|
|
29
|
+
export function detectAppExcessiveGraphPerms(apps: AzureApp[], includeDetails: boolean): Finding {
|
|
30
|
+
// Well-known Microsoft Graph Application Permission GUIDs
|
|
31
|
+
const dangerousPermissionIds = [
|
|
32
|
+
'1bfefb4e-e0b5-418b-a88f-73c46d1986e9', // Application.ReadWrite.All
|
|
33
|
+
'19dbc75e-c2e2-444c-a770-ec69d8559fc7', // Directory.ReadWrite.All
|
|
34
|
+
'9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8', // RoleManagement.ReadWrite.Directory
|
|
35
|
+
'741f803b-c850-494e-b5df-cde7c675a1ca', // User.ReadWrite.All
|
|
36
|
+
'62a82d76-70ea-41e2-9197-370581804d09', // Group.ReadWrite.All
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const dangerousPermissionNames = [
|
|
40
|
+
'Application.ReadWrite.All',
|
|
41
|
+
'Directory.ReadWrite.All',
|
|
42
|
+
'RoleManagement.ReadWrite.Directory',
|
|
43
|
+
'User.ReadWrite.All',
|
|
44
|
+
'Group.ReadWrite.All',
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const affected = apps.filter((app) => {
|
|
48
|
+
const permissions = (app as any).requiredResourceAccess || [];
|
|
49
|
+
return permissions.some((resource: any) => {
|
|
50
|
+
if (resource.resourceAppId === '00000003-0000-0000-c000-000000000000') {
|
|
51
|
+
// Microsoft Graph
|
|
52
|
+
return resource.resourceAccess?.some((access: any) => {
|
|
53
|
+
// Check by GUID
|
|
54
|
+
if (dangerousPermissionIds.includes(access.id)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
// Check by permission name (if available)
|
|
58
|
+
if (access.value && dangerousPermissionNames.includes(access.value)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
type: 'AZURE_APP_EXCESSIVE_GRAPH_PERMS',
|
|
70
|
+
severity: 'critical',
|
|
71
|
+
category: 'applications',
|
|
72
|
+
title: 'Excessive Microsoft Graph Permissions',
|
|
73
|
+
description: 'Application with high-privilege Graph API permissions. Can access sensitive data across tenant.',
|
|
74
|
+
count: affected.length,
|
|
75
|
+
affectedEntities: includeDetails ? toAffectedAppEntities(affected) : undefined,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check for applications with expired credentials
|
|
81
|
+
*/
|
|
82
|
+
export function detectAppCredentialExpired(apps: AzureApp[], includeDetails: boolean): Finding {
|
|
83
|
+
const now = Date.now();
|
|
84
|
+
|
|
85
|
+
const affected = apps.filter((app) => {
|
|
86
|
+
const credentials = [
|
|
87
|
+
...((app as any).passwordCredentials || []),
|
|
88
|
+
...((app as any).keyCredentials || []),
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
return credentials.some((cred: any) => {
|
|
92
|
+
if (!cred.endDateTime) return false;
|
|
93
|
+
return new Date(cred.endDateTime).getTime() < now;
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
type: 'AZURE_APP_CREDENTIAL_EXPIRED',
|
|
99
|
+
severity: 'high',
|
|
100
|
+
category: 'applications',
|
|
101
|
+
title: 'Application Credential Expired',
|
|
102
|
+
description: 'Application with expired secret or certificate. May cause service disruption.',
|
|
103
|
+
count: affected.length,
|
|
104
|
+
affectedEntities: includeDetails ? toAffectedAppEntities(affected) : undefined,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Check for applications with long-lived credentials (>1 year)
|
|
110
|
+
*/
|
|
111
|
+
export function detectAppLongLivedCreds(apps: AzureApp[], includeDetails: boolean): Finding {
|
|
112
|
+
const now = Date.now();
|
|
113
|
+
const oneYearFromNow = now + 365 * 24 * 60 * 60 * 1000;
|
|
114
|
+
|
|
115
|
+
const affected = apps.filter((app) => {
|
|
116
|
+
const credentials = [
|
|
117
|
+
...((app as any).passwordCredentials || []),
|
|
118
|
+
...((app as any).keyCredentials || []),
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
return credentials.some((cred: any) => {
|
|
122
|
+
if (!cred.endDateTime) return false;
|
|
123
|
+
return new Date(cred.endDateTime).getTime() > oneYearFromNow;
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
type: 'AZURE_APP_LONG_LIVED_CREDS',
|
|
129
|
+
severity: 'high',
|
|
130
|
+
category: 'applications',
|
|
131
|
+
title: 'Long-Lived Application Credentials',
|
|
132
|
+
description: 'Application credential valid for more than 1 year. Increases risk if credential is compromised.',
|
|
133
|
+
count: affected.length,
|
|
134
|
+
affectedEntities: includeDetails ? toAffectedAppEntities(affected) : undefined,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Check for unverified multi-tenant applications
|
|
140
|
+
*/
|
|
141
|
+
export function detectAppMultitenantUnverified(apps: AzureApp[], includeDetails: boolean): Finding {
|
|
142
|
+
const affected = apps.filter((app) => {
|
|
143
|
+
const isMultiTenant = app.signInAudience === 'AzureADMultipleOrgs' || app.signInAudience === 'AzureADandPersonalMicrosoftAccount';
|
|
144
|
+
const isVerified = (app as any).publisherDomain && (app as any).verifiedPublisher;
|
|
145
|
+
|
|
146
|
+
return isMultiTenant && !isVerified;
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
type: 'AZURE_APP_MULTITENANT_UNVERIFIED',
|
|
151
|
+
severity: 'high',
|
|
152
|
+
category: 'applications',
|
|
153
|
+
title: 'Unverified Multi-Tenant Application',
|
|
154
|
+
description: 'Multi-tenant application without verified publisher. Users from other tenants may be at risk.',
|
|
155
|
+
count: affected.length,
|
|
156
|
+
affectedEntities: includeDetails ? toAffectedAppEntities(affected) : undefined,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Check for applications with credentials expiring soon (30 days)
|
|
162
|
+
*/
|
|
163
|
+
export function detectAppCredentialExpiring(apps: AzureApp[], includeDetails: boolean): Finding {
|
|
164
|
+
const now = Date.now();
|
|
165
|
+
const thirtyDaysFromNow = now + 30 * 24 * 60 * 60 * 1000;
|
|
166
|
+
|
|
167
|
+
const affected = apps.filter((app) => {
|
|
168
|
+
const credentials = [
|
|
169
|
+
...((app as any).passwordCredentials || []),
|
|
170
|
+
...((app as any).keyCredentials || []),
|
|
171
|
+
];
|
|
172
|
+
|
|
173
|
+
return credentials.some((cred: any) => {
|
|
174
|
+
if (!cred.endDateTime) return false;
|
|
175
|
+
const expiry = new Date(cred.endDateTime).getTime();
|
|
176
|
+
return expiry > now && expiry < thirtyDaysFromNow;
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
type: 'AZURE_APP_CREDENTIAL_EXPIRING',
|
|
182
|
+
severity: 'medium',
|
|
183
|
+
category: 'applications',
|
|
184
|
+
title: 'Application Credential Expiring Soon',
|
|
185
|
+
description: 'Application credential expiring within 30 days. Action required to avoid service disruption.',
|
|
186
|
+
count: affected.length,
|
|
187
|
+
affectedEntities: includeDetails ? toAffectedAppEntities(affected) : undefined,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Check for disabled service principals with credentials
|
|
193
|
+
*/
|
|
194
|
+
export function detectSpDisabledWithCreds(apps: AzureApp[], includeDetails: boolean): Finding {
|
|
195
|
+
const affected = apps.filter((app) => {
|
|
196
|
+
const isDisabled = (app as any).accountEnabled === false;
|
|
197
|
+
const hasCredentials = ((app as any).passwordCredentials?.length > 0) || ((app as any).keyCredentials?.length > 0);
|
|
198
|
+
|
|
199
|
+
return isDisabled && hasCredentials;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
type: 'AZURE_SP_DISABLED_WITH_CREDS',
|
|
204
|
+
severity: 'medium',
|
|
205
|
+
category: 'applications',
|
|
206
|
+
title: 'Disabled Service Principal with Credentials',
|
|
207
|
+
description: 'Disabled service principal still has active credentials. Credentials should be removed.',
|
|
208
|
+
count: affected.length,
|
|
209
|
+
affectedEntities: includeDetails ? toAffectedAppEntities(affected) : undefined,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Check for applications without owners
|
|
215
|
+
*/
|
|
216
|
+
export function detectAppNoOwner(apps: AzureApp[], includeDetails: boolean): Finding {
|
|
217
|
+
const affected = apps.filter((app) => {
|
|
218
|
+
const owners = (app as any).owners || [];
|
|
219
|
+
return owners.length === 0;
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
type: 'AZURE_APP_NO_OWNER',
|
|
224
|
+
severity: 'medium',
|
|
225
|
+
category: 'applications',
|
|
226
|
+
title: 'Application without Owner',
|
|
227
|
+
description: 'Application has no assigned owners. Orphaned applications are difficult to manage.',
|
|
228
|
+
count: affected.length,
|
|
229
|
+
affectedEntities: includeDetails ? toAffectedAppEntities(affected) : undefined,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Detect all application security vulnerabilities
|
|
235
|
+
*/
|
|
236
|
+
export function detectAppSecurityVulnerabilities(apps: AzureApp[], includeDetails: boolean): Finding[] {
|
|
237
|
+
return [
|
|
238
|
+
detectAppExcessiveGraphPerms(apps, includeDetails),
|
|
239
|
+
detectAppCredentialExpired(apps, includeDetails),
|
|
240
|
+
detectAppLongLivedCreds(apps, includeDetails),
|
|
241
|
+
detectAppMultitenantUnverified(apps, includeDetails),
|
|
242
|
+
detectAppCredentialExpiring(apps, includeDetails),
|
|
243
|
+
detectSpDisabledWithCreds(apps, includeDetails),
|
|
244
|
+
detectAppNoOwner(apps, includeDetails),
|
|
245
|
+
].filter((finding) => finding.count > 0);
|
|
246
|
+
}
|