contrast-agent 3.8.4

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 (500) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +5 -0
  3. data/.dockerignore +10 -0
  4. data/.gitignore +58 -0
  5. data/.gitmodules +6 -0
  6. data/.rspec +6 -0
  7. data/.simplecov +4 -0
  8. data/Gemfile +7 -0
  9. data/LICENSE.txt +12 -0
  10. data/Rakefile +15 -0
  11. data/exe/contrast_service +29 -0
  12. data/ext/build_funchook.rb +48 -0
  13. data/ext/cs__assess_active_record_named/cs__active_record_named.c +47 -0
  14. data/ext/cs__assess_active_record_named/cs__active_record_named.h +10 -0
  15. data/ext/cs__assess_active_record_named/extconf.rb +2 -0
  16. data/ext/cs__assess_array/cs__assess_array.c +38 -0
  17. data/ext/cs__assess_array/cs__assess_array.h +9 -0
  18. data/ext/cs__assess_array/extconf.rb +2 -0
  19. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +50 -0
  20. data/ext/cs__assess_basic_object/cs__assess_basic_object.h +17 -0
  21. data/ext/cs__assess_basic_object/extconf.rb +2 -0
  22. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +86 -0
  23. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +34 -0
  24. data/ext/cs__assess_fiber_track/extconf.rb +2 -0
  25. data/ext/cs__assess_hash/cs__assess_hash.c +64 -0
  26. data/ext/cs__assess_hash/cs__assess_hash.h +24 -0
  27. data/ext/cs__assess_hash/extconf.rb +2 -0
  28. data/ext/cs__assess_kernel/cs__assess_kernel.c +36 -0
  29. data/ext/cs__assess_kernel/cs__assess_kernel.h +10 -0
  30. data/ext/cs__assess_kernel/extconf.rb +2 -0
  31. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +47 -0
  32. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +18 -0
  33. data/ext/cs__assess_marshal_module/extconf.rb +2 -0
  34. data/ext/cs__assess_module/cs__assess_module.c +78 -0
  35. data/ext/cs__assess_module/cs__assess_module.h +25 -0
  36. data/ext/cs__assess_module/extconf.rb +2 -0
  37. data/ext/cs__assess_regexp/cs__assess_regexp.c +48 -0
  38. data/ext/cs__assess_regexp/cs__assess_regexp.h +22 -0
  39. data/ext/cs__assess_regexp/extconf.rb +2 -0
  40. data/ext/cs__assess_regexp_track/cs__assess_regexp_track.c +63 -0
  41. data/ext/cs__assess_regexp_track/cs__assess_regexp_track.h +29 -0
  42. data/ext/cs__assess_regexp_track/extconf.rb +2 -0
  43. data/ext/cs__assess_string/cs__assess_string.c +38 -0
  44. data/ext/cs__assess_string/cs__assess_string.h +19 -0
  45. data/ext/cs__assess_string/extconf.rb +2 -0
  46. data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +31 -0
  47. data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.h +13 -0
  48. data/ext/cs__assess_string_interpolation26/extconf.rb +2 -0
  49. data/ext/cs__common/cs__common.c +60 -0
  50. data/ext/cs__common/cs__common.h +28 -0
  51. data/ext/cs__common/extconf.rb +20 -0
  52. data/ext/cs__contrast_patch/cs__contrast_patch.c +445 -0
  53. data/ext/cs__contrast_patch/cs__contrast_patch.h +196 -0
  54. data/ext/cs__contrast_patch/extconf.rb +2 -0
  55. data/ext/cs__protect_kernel/cs__protect_kernel.c +37 -0
  56. data/ext/cs__protect_kernel/cs__protect_kernel.h +11 -0
  57. data/ext/cs__protect_kernel/extconf.rb +2 -0
  58. data/ext/cs__scope/cs__scope.c +96 -0
  59. data/ext/cs__scope/cs__scope.h +33 -0
  60. data/ext/cs__scope/extconf.rb +2 -0
  61. data/ext/extconf_common.rb +49 -0
  62. data/funchook/LICENSE +360 -0
  63. data/funchook/Makefile +29 -0
  64. data/funchook/Makefile.in +29 -0
  65. data/funchook/README.md +121 -0
  66. data/funchook/appveyor.yml +42 -0
  67. data/funchook/autogen.sh +3 -0
  68. data/funchook/autom4te.cache/output.0 +4976 -0
  69. data/funchook/autom4te.cache/requests +78 -0
  70. data/funchook/autom4te.cache/traces.0 +364 -0
  71. data/funchook/config.guess +1530 -0
  72. data/funchook/config.log +490 -0
  73. data/funchook/config.status +1016 -0
  74. data/funchook/config.sub +1773 -0
  75. data/funchook/configure +4976 -0
  76. data/funchook/configure.ac +59 -0
  77. data/funchook/distorm/COPYING +26 -0
  78. data/funchook/distorm/MANIFEST +25 -0
  79. data/funchook/distorm/MANIFEST.in +4 -0
  80. data/funchook/distorm/README.md +12 -0
  81. data/funchook/distorm/disOps/disOps.py +795 -0
  82. data/funchook/distorm/disOps/x86db.py +404 -0
  83. data/funchook/distorm/disOps/x86header.py +247 -0
  84. data/funchook/distorm/disOps/x86sets.py +1664 -0
  85. data/funchook/distorm/examples/cs/TestdiStorm/Program.cs +79 -0
  86. data/funchook/distorm/examples/cs/TestdiStorm/Properties/AssemblyInfo.cs +36 -0
  87. data/funchook/distorm/examples/cs/TestdiStorm/TestdiStorm.csproj +69 -0
  88. data/funchook/distorm/examples/cs/distorm-net.sln +26 -0
  89. data/funchook/distorm/examples/cs/distorm-net/CodeInfo.cs +23 -0
  90. data/funchook/distorm/examples/cs/distorm-net/DecodedInst.cs +15 -0
  91. data/funchook/distorm/examples/cs/distorm-net/DecodedResult.cs +14 -0
  92. data/funchook/distorm/examples/cs/distorm-net/DecomposedInst.cs +36 -0
  93. data/funchook/distorm/examples/cs/distorm-net/DecomposedResult.cs +14 -0
  94. data/funchook/distorm/examples/cs/distorm-net/Opcodes.cs +1268 -0
  95. data/funchook/distorm/examples/cs/distorm-net/Opcodes.tt +37 -0
  96. data/funchook/distorm/examples/cs/distorm-net/Operand.cs +25 -0
  97. data/funchook/distorm/examples/cs/distorm-net/Properties/AssemblyInfo.cs +36 -0
  98. data/funchook/distorm/examples/cs/distorm-net/diStorm3.cs +411 -0
  99. data/funchook/distorm/examples/cs/distorm-net/distorm-net.csproj +80 -0
  100. data/funchook/distorm/examples/cs/readme +3 -0
  101. data/funchook/distorm/examples/ddk/README +48 -0
  102. data/funchook/distorm/examples/ddk/distorm.ini +11 -0
  103. data/funchook/distorm/examples/ddk/dummy.c +15 -0
  104. data/funchook/distorm/examples/ddk/main.c +91 -0
  105. data/funchook/distorm/examples/ddk/makefile +1 -0
  106. data/funchook/distorm/examples/ddk/sources +10 -0
  107. data/funchook/distorm/examples/java/Makefile +23 -0
  108. data/funchook/distorm/examples/java/distorm/src/Main.java +43 -0
  109. data/funchook/distorm/examples/java/distorm/src/diStorm3/CodeInfo.java +27 -0
  110. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedInst.java +32 -0
  111. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedResult.java +11 -0
  112. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedInst.java +89 -0
  113. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedResult.java +11 -0
  114. data/funchook/distorm/examples/java/distorm/src/diStorm3/OpcodeEnum.java +131 -0
  115. data/funchook/distorm/examples/java/distorm/src/diStorm3/Opcodes.java +1123 -0
  116. data/funchook/distorm/examples/java/distorm/src/diStorm3/Operand.java +24 -0
  117. data/funchook/distorm/examples/java/distorm/src/diStorm3/distorm3.java +41 -0
  118. data/funchook/distorm/examples/java/jdistorm.c +405 -0
  119. data/funchook/distorm/examples/java/jdistorm.h +40 -0
  120. data/funchook/distorm/examples/java/jdistorm.sln +20 -0
  121. data/funchook/distorm/examples/java/jdistorm.vcproj +208 -0
  122. data/funchook/distorm/examples/linux/Makefile +15 -0
  123. data/funchook/distorm/examples/linux/main.c +181 -0
  124. data/funchook/distorm/examples/tests/Makefile +15 -0
  125. data/funchook/distorm/examples/tests/main.cpp +42 -0
  126. data/funchook/distorm/examples/tests/main.py +66 -0
  127. data/funchook/distorm/examples/tests/test_distorm3.py +1672 -0
  128. data/funchook/distorm/examples/tests/tests.sln +20 -0
  129. data/funchook/distorm/examples/tests/tests.vcxproj +82 -0
  130. data/funchook/distorm/examples/tests/tests.vcxproj.filters +22 -0
  131. data/funchook/distorm/examples/win32/disasm.sln +25 -0
  132. data/funchook/distorm/examples/win32/disasm.vcxproj +201 -0
  133. data/funchook/distorm/examples/win32/disasm.vcxproj.filters +14 -0
  134. data/funchook/distorm/examples/win32/main.cpp +163 -0
  135. data/funchook/distorm/include/distorm.h +482 -0
  136. data/funchook/distorm/include/mnemonics.h +301 -0
  137. data/funchook/distorm/make/linux/Makefile +28 -0
  138. data/funchook/distorm/make/mac/Makefile +24 -0
  139. data/funchook/distorm/make/win32/cdistorm.vcxproj +239 -0
  140. data/funchook/distorm/make/win32/cdistorm.vcxproj.filters +80 -0
  141. data/funchook/distorm/make/win32/distorm.sln +25 -0
  142. data/funchook/distorm/make/win32/resource.h +14 -0
  143. data/funchook/distorm/make/win32/resource.rc +99 -0
  144. data/funchook/distorm/python/distorm3/__init__.py +957 -0
  145. data/funchook/distorm/python/distorm3/sample.py +51 -0
  146. data/funchook/distorm/setup.cfg +10 -0
  147. data/funchook/distorm/setup.py +266 -0
  148. data/funchook/distorm/src/config.h +169 -0
  149. data/funchook/distorm/src/decoder.c +641 -0
  150. data/funchook/distorm/src/decoder.h +33 -0
  151. data/funchook/distorm/src/distorm.c +413 -0
  152. data/funchook/distorm/src/instructions.c +597 -0
  153. data/funchook/distorm/src/instructions.h +463 -0
  154. data/funchook/distorm/src/insts.c +7939 -0
  155. data/funchook/distorm/src/insts.h +64 -0
  156. data/funchook/distorm/src/mnemonics.c +284 -0
  157. data/funchook/distorm/src/operands.c +1290 -0
  158. data/funchook/distorm/src/operands.h +28 -0
  159. data/funchook/distorm/src/prefix.c +368 -0
  160. data/funchook/distorm/src/prefix.h +64 -0
  161. data/funchook/distorm/src/textdefs.c +172 -0
  162. data/funchook/distorm/src/textdefs.h +57 -0
  163. data/funchook/distorm/src/wstring.c +47 -0
  164. data/funchook/distorm/src/wstring.h +35 -0
  165. data/funchook/distorm/src/x86defs.h +82 -0
  166. data/funchook/include/funchook.h +123 -0
  167. data/funchook/install-sh +527 -0
  168. data/funchook/src/Makefile +70 -0
  169. data/funchook/src/Makefile.in +70 -0
  170. data/funchook/src/__strerror.h +109 -0
  171. data/funchook/src/config.h +101 -0
  172. data/funchook/src/config.h.in +100 -0
  173. data/funchook/src/decoder.o +0 -0
  174. data/funchook/src/distorm.o +0 -0
  175. data/funchook/src/funchook.c +440 -0
  176. data/funchook/src/funchook.o +0 -0
  177. data/funchook/src/funchook_internal.h +155 -0
  178. data/funchook/src/funchook_io.c +182 -0
  179. data/funchook/src/funchook_io.h +64 -0
  180. data/funchook/src/funchook_io.o +0 -0
  181. data/funchook/src/funchook_syscall.S +134 -0
  182. data/funchook/src/funchook_syscall.o +0 -0
  183. data/funchook/src/funchook_unix.c +480 -0
  184. data/funchook/src/funchook_unix.o +0 -0
  185. data/funchook/src/funchook_windows.c +397 -0
  186. data/funchook/src/funchook_x86.c +622 -0
  187. data/funchook/src/funchook_x86.o +0 -0
  188. data/funchook/src/instructions.o +0 -0
  189. data/funchook/src/insts.o +0 -0
  190. data/funchook/src/libfunchook.so +0 -0
  191. data/funchook/src/mnemonics.o +0 -0
  192. data/funchook/src/operands.o +0 -0
  193. data/funchook/src/os_func.c +115 -0
  194. data/funchook/src/os_func.h +75 -0
  195. data/funchook/src/os_func.o +0 -0
  196. data/funchook/src/os_func_unix.c +94 -0
  197. data/funchook/src/os_func_unix.o +0 -0
  198. data/funchook/src/os_func_windows.c +32 -0
  199. data/funchook/src/prefix.o +0 -0
  200. data/funchook/src/printf_base.c +1688 -0
  201. data/funchook/src/printf_base.h +46 -0
  202. data/funchook/src/printf_base.o +0 -0
  203. data/funchook/src/textdefs.o +0 -0
  204. data/funchook/src/wstring.o +0 -0
  205. data/funchook/test/Makefile +43 -0
  206. data/funchook/test/Makefile.in +43 -0
  207. data/funchook/test/funchook_test +0 -0
  208. data/funchook/test/libfunchook_test.c +25 -0
  209. data/funchook/test/libfunchook_test.so +0 -0
  210. data/funchook/test/libfunchook_test2.c +18 -0
  211. data/funchook/test/suffix.list +600 -0
  212. data/funchook/test/test_main.c +430 -0
  213. data/funchook/test/test_main.o +0 -0
  214. data/funchook/test/x86_64_test.S +10 -0
  215. data/funchook/test/x86_64_test.o +0 -0
  216. data/funchook/test/x86_test.S +339 -0
  217. data/funchook/win32/config.h +1 -0
  218. data/funchook/win32/funchook.sln +52 -0
  219. data/funchook/win32/funchook.vcxproj +188 -0
  220. data/funchook/win32/funchook.vcxproj.filters +84 -0
  221. data/funchook/win32/funchook_test.vcxproj +170 -0
  222. data/funchook/win32/funchook_test.vcxproj.filters +22 -0
  223. data/funchook/win32/funchook_test_dll.vcxproj +184 -0
  224. data/funchook/win32/funchook_test_dll.vcxproj.filters +30 -0
  225. data/funchook/win32/funchook_test_exe.def +3 -0
  226. data/lib/contrast-agent.rb +8 -0
  227. data/lib/contrast.rb +57 -0
  228. data/lib/contrast/agent.rb +80 -0
  229. data/lib/contrast/agent/assess.rb +45 -0
  230. data/lib/contrast/agent/assess/adjusted_span.rb +25 -0
  231. data/lib/contrast/agent/assess/class_reverter.rb +82 -0
  232. data/lib/contrast/agent/assess/contrast_event.rb +398 -0
  233. data/lib/contrast/agent/assess/frozen_properties.rb +41 -0
  234. data/lib/contrast/agent/assess/insulator.rb +53 -0
  235. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +78 -0
  236. data/lib/contrast/agent/assess/policy/patcher.rb +85 -0
  237. data/lib/contrast/agent/assess/policy/policy.rb +116 -0
  238. data/lib/contrast/agent/assess/policy/policy_node.rb +289 -0
  239. data/lib/contrast/agent/assess/policy/policy_scanner.rb +44 -0
  240. data/lib/contrast/agent/assess/policy/preshift.rb +94 -0
  241. data/lib/contrast/agent/assess/policy/propagation_method.rb +260 -0
  242. data/lib/contrast/agent/assess/policy/propagation_node.rb +127 -0
  243. data/lib/contrast/agent/assess/policy/propagator.rb +35 -0
  244. data/lib/contrast/agent/assess/policy/propagator/append.rb +54 -0
  245. data/lib/contrast/agent/assess/policy/propagator/base.rb +37 -0
  246. data/lib/contrast/agent/assess/policy/propagator/center.rb +73 -0
  247. data/lib/contrast/agent/assess/policy/propagator/custom.rb +36 -0
  248. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +62 -0
  249. data/lib/contrast/agent/assess/policy/propagator/insert.rb +55 -0
  250. data/lib/contrast/agent/assess/policy/propagator/keep.rb +26 -0
  251. data/lib/contrast/agent/assess/policy/propagator/next.rb +42 -0
  252. data/lib/contrast/agent/assess/policy/propagator/prepend.rb +50 -0
  253. data/lib/contrast/agent/assess/policy/propagator/remove.rb +76 -0
  254. data/lib/contrast/agent/assess/policy/propagator/replace.rb +27 -0
  255. data/lib/contrast/agent/assess/policy/propagator/reverse.rb +38 -0
  256. data/lib/contrast/agent/assess/policy/propagator/select.rb +86 -0
  257. data/lib/contrast/agent/assess/policy/propagator/splat.rb +60 -0
  258. data/lib/contrast/agent/assess/policy/propagator/split.rb +49 -0
  259. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +169 -0
  260. data/lib/contrast/agent/assess/policy/propagator/trim.rb +81 -0
  261. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +79 -0
  262. data/lib/contrast/agent/assess/policy/source_method.rb +209 -0
  263. data/lib/contrast/agent/assess/policy/source_node.rb +62 -0
  264. data/lib/contrast/agent/assess/policy/trigger_method.rb +209 -0
  265. data/lib/contrast/agent/assess/policy/trigger_node.rb +198 -0
  266. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +77 -0
  267. data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +31 -0
  268. data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +40 -0
  269. data/lib/contrast/agent/assess/properties.rb +392 -0
  270. data/lib/contrast/agent/assess/rule.rb +18 -0
  271. data/lib/contrast/agent/assess/rule/base.rb +72 -0
  272. data/lib/contrast/agent/assess/rule/csrf.rb +66 -0
  273. data/lib/contrast/agent/assess/rule/csrf/csrf_action.rb +28 -0
  274. data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +69 -0
  275. data/lib/contrast/agent/assess/rule/csrf/csrf_watcher.rb +132 -0
  276. data/lib/contrast/agent/assess/rule/provider.rb +21 -0
  277. data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +62 -0
  278. data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +73 -0
  279. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +121 -0
  280. data/lib/contrast/agent/assess/rule/redos.rb +68 -0
  281. data/lib/contrast/agent/assess/rule/response_scanning_rule.rb +47 -0
  282. data/lib/contrast/agent/assess/rule/response_watcher.rb +36 -0
  283. data/lib/contrast/agent/assess/rule/watcher.rb +36 -0
  284. data/lib/contrast/agent/assess/tag.rb +151 -0
  285. data/lib/contrast/agent/at_exit_hook.rb +33 -0
  286. data/lib/contrast/agent/class_reopener.rb +195 -0
  287. data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +26 -0
  288. data/lib/contrast/agent/deadzone/policy/policy.rb +57 -0
  289. data/lib/contrast/agent/disable_reaction.rb +24 -0
  290. data/lib/contrast/agent/exclusion_matcher.rb +190 -0
  291. data/lib/contrast/agent/feature_state.rb +379 -0
  292. data/lib/contrast/agent/inventory/policy/policy.rb +32 -0
  293. data/lib/contrast/agent/inventory/policy/trigger_node.rb +22 -0
  294. data/lib/contrast/agent/logger_manager.rb +116 -0
  295. data/lib/contrast/agent/middleware.rb +352 -0
  296. data/lib/contrast/agent/module_data.rb +16 -0
  297. data/lib/contrast/agent/patching/policy/after_load_patch.rb +37 -0
  298. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +58 -0
  299. data/lib/contrast/agent/patching/policy/method_policy.rb +94 -0
  300. data/lib/contrast/agent/patching/policy/module_policy.rb +116 -0
  301. data/lib/contrast/agent/patching/policy/patch.rb +312 -0
  302. data/lib/contrast/agent/patching/policy/patch_status.rb +192 -0
  303. data/lib/contrast/agent/patching/policy/patcher.rb +310 -0
  304. data/lib/contrast/agent/patching/policy/policy.rb +138 -0
  305. data/lib/contrast/agent/patching/policy/policy_node.rb +80 -0
  306. data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +28 -0
  307. data/lib/contrast/agent/patching/policy/trigger_node.rb +81 -0
  308. data/lib/contrast/agent/protect/policy/policy.rb +37 -0
  309. data/lib/contrast/agent/protect/policy/trigger_node.rb +23 -0
  310. data/lib/contrast/agent/protect/rule.rb +58 -0
  311. data/lib/contrast/agent/protect/rule/base.rb +300 -0
  312. data/lib/contrast/agent/protect/rule/base_service.rb +88 -0
  313. data/lib/contrast/agent/protect/rule/cmd_injection.rb +156 -0
  314. data/lib/contrast/agent/protect/rule/csrf.rb +118 -0
  315. data/lib/contrast/agent/protect/rule/csrf/csrf_evaluator.rb +103 -0
  316. data/lib/contrast/agent/protect/rule/csrf/csrf_token_injector.rb +85 -0
  317. data/lib/contrast/agent/protect/rule/default_scanner.rb +300 -0
  318. data/lib/contrast/agent/protect/rule/deserialization.rb +193 -0
  319. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +80 -0
  320. data/lib/contrast/agent/protect/rule/no_sqli.rb +101 -0
  321. data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +40 -0
  322. data/lib/contrast/agent/protect/rule/path_traversal.rb +143 -0
  323. data/lib/contrast/agent/protect/rule/sqli.rb +101 -0
  324. data/lib/contrast/agent/protect/rule/sqli/default_sql_scanner.rb +16 -0
  325. data/lib/contrast/agent/protect/rule/sqli/mysql_sql_scanner.rb +38 -0
  326. data/lib/contrast/agent/protect/rule/sqli/postgres_sql_scanner.rb +22 -0
  327. data/lib/contrast/agent/protect/rule/sqli/sqlite_sql_scanner.rb +19 -0
  328. data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +20 -0
  329. data/lib/contrast/agent/protect/rule/xss.rb +24 -0
  330. data/lib/contrast/agent/protect/rule/xxe.rb +120 -0
  331. data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +82 -0
  332. data/lib/contrast/agent/railtie.rb +30 -0
  333. data/lib/contrast/agent/reaction_processor.rb +47 -0
  334. data/lib/contrast/agent/request.rb +493 -0
  335. data/lib/contrast/agent/request_context.rb +225 -0
  336. data/lib/contrast/agent/require_state.rb +61 -0
  337. data/lib/contrast/agent/response.rb +215 -0
  338. data/lib/contrast/agent/rewriter.rb +244 -0
  339. data/lib/contrast/agent/scope.rb +28 -0
  340. data/lib/contrast/agent/service_heartbeat.rb +37 -0
  341. data/lib/contrast/agent/settings_state.rb +148 -0
  342. data/lib/contrast/agent/socket_client.rb +125 -0
  343. data/lib/contrast/agent/thread.rb +26 -0
  344. data/lib/contrast/agent/tracepoint_hook.rb +51 -0
  345. data/lib/contrast/agent/version.rb +8 -0
  346. data/lib/contrast/api.rb +17 -0
  347. data/lib/contrast/api/.gitkeep +0 -0
  348. data/lib/contrast/api/connection_status.rb +49 -0
  349. data/lib/contrast/api/socket.rb +43 -0
  350. data/lib/contrast/api/speedracer.rb +206 -0
  351. data/lib/contrast/api/tcp_socket.rb +31 -0
  352. data/lib/contrast/api/unix_socket.rb +25 -0
  353. data/lib/contrast/common_agent_configuration.rb +86 -0
  354. data/lib/contrast/components/agent.rb +85 -0
  355. data/lib/contrast/components/app_context.rb +188 -0
  356. data/lib/contrast/components/assess.rb +67 -0
  357. data/lib/contrast/components/config.rb +135 -0
  358. data/lib/contrast/components/contrast_service.rb +113 -0
  359. data/lib/contrast/components/heap_dump.rb +34 -0
  360. data/lib/contrast/components/interface.rb +178 -0
  361. data/lib/contrast/components/inventory.rb +23 -0
  362. data/lib/contrast/components/logger.rb +92 -0
  363. data/lib/contrast/components/protect.rb +38 -0
  364. data/lib/contrast/components/sampling.rb +41 -0
  365. data/lib/contrast/components/scope.rb +106 -0
  366. data/lib/contrast/components/settings.rb +140 -0
  367. data/lib/contrast/config.rb +33 -0
  368. data/lib/contrast/config/agent_configuration.rb +24 -0
  369. data/lib/contrast/config/application_configuration.rb +27 -0
  370. data/lib/contrast/config/assess_configuration.rb +22 -0
  371. data/lib/contrast/config/assess_rules_configuration.rb +18 -0
  372. data/lib/contrast/config/base_configuration.rb +105 -0
  373. data/lib/contrast/config/default_value.rb +16 -0
  374. data/lib/contrast/config/exception_configuration.rb +21 -0
  375. data/lib/contrast/config/heap_dump_configuration.rb +23 -0
  376. data/lib/contrast/config/inventory_configuration.rb +20 -0
  377. data/lib/contrast/config/logger_configuration.rb +20 -0
  378. data/lib/contrast/config/protect_configuration.rb +20 -0
  379. data/lib/contrast/config/protect_rule_configuration.rb +37 -0
  380. data/lib/contrast/config/protect_rules_configuration.rb +30 -0
  381. data/lib/contrast/config/root_configuration.rb +26 -0
  382. data/lib/contrast/config/ruby_configuration.rb +39 -0
  383. data/lib/contrast/config/sampling_configuration.rb +22 -0
  384. data/lib/contrast/config/server_configuration.rb +23 -0
  385. data/lib/contrast/config/service_configuration.rb +22 -0
  386. data/lib/contrast/configuration.rb +214 -0
  387. data/lib/contrast/core_extensions/assess.rb +51 -0
  388. data/lib/contrast/core_extensions/assess/array.rb +58 -0
  389. data/lib/contrast/core_extensions/assess/assess_extension.rb +145 -0
  390. data/lib/contrast/core_extensions/assess/basic_object.rb +15 -0
  391. data/lib/contrast/core_extensions/assess/erb.rb +42 -0
  392. data/lib/contrast/core_extensions/assess/exec_trigger.rb +48 -0
  393. data/lib/contrast/core_extensions/assess/fiber.rb +125 -0
  394. data/lib/contrast/core_extensions/assess/hash.rb +22 -0
  395. data/lib/contrast/core_extensions/assess/kernel.rb +95 -0
  396. data/lib/contrast/core_extensions/assess/module.rb +14 -0
  397. data/lib/contrast/core_extensions/assess/regexp.rb +206 -0
  398. data/lib/contrast/core_extensions/assess/string.rb +75 -0
  399. data/lib/contrast/core_extensions/assess/tilt_template_trigger.rb +73 -0
  400. data/lib/contrast/core_extensions/delegator.rb +14 -0
  401. data/lib/contrast/core_extensions/eval_trigger.rb +52 -0
  402. data/lib/contrast/core_extensions/inventory.rb +22 -0
  403. data/lib/contrast/core_extensions/inventory/datastores.rb +37 -0
  404. data/lib/contrast/core_extensions/module.rb +42 -0
  405. data/lib/contrast/core_extensions/object.rb +27 -0
  406. data/lib/contrast/core_extensions/protect.rb +20 -0
  407. data/lib/contrast/core_extensions/protect/applies_command_injection_rule.rb +70 -0
  408. data/lib/contrast/core_extensions/protect/applies_deserialization_rule.rb +58 -0
  409. data/lib/contrast/core_extensions/protect/applies_no_sqli_rule.rb +81 -0
  410. data/lib/contrast/core_extensions/protect/applies_path_traversal_rule.rb +119 -0
  411. data/lib/contrast/core_extensions/protect/applies_sqli_rule.rb +63 -0
  412. data/lib/contrast/core_extensions/protect/applies_xxe_rule.rb +141 -0
  413. data/lib/contrast/core_extensions/protect/kernel.rb +30 -0
  414. data/lib/contrast/core_extensions/protect/psych.rb +7 -0
  415. data/lib/contrast/core_extensions/thread.rb +31 -0
  416. data/lib/contrast/internal_exception.rb +8 -0
  417. data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +48 -0
  418. data/lib/contrast/rails_extensions/assess/active_record.rb +32 -0
  419. data/lib/contrast/rails_extensions/assess/active_record_named.rb +61 -0
  420. data/lib/contrast/rails_extensions/assess/configuration.rb +26 -0
  421. data/lib/contrast/rails_extensions/buffer.rb +30 -0
  422. data/lib/contrast/rails_extensions/rack.rb +45 -0
  423. data/lib/contrast/security_exception.rb +14 -0
  424. data/lib/contrast/sinatra_extensions/assess/cookie.rb +26 -0
  425. data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +59 -0
  426. data/lib/contrast/tasks/service.rb +95 -0
  427. data/lib/contrast/utils/assess/sampling_util.rb +96 -0
  428. data/lib/contrast/utils/assess/tracking_util.rb +39 -0
  429. data/lib/contrast/utils/boolean_util.rb +33 -0
  430. data/lib/contrast/utils/cache.rb +69 -0
  431. data/lib/contrast/utils/class_util.rb +58 -0
  432. data/lib/contrast/utils/comment_range.rb +19 -0
  433. data/lib/contrast/utils/data_store_util.rb +23 -0
  434. data/lib/contrast/utils/duck_utils.rb +58 -0
  435. data/lib/contrast/utils/env_configuration_item.rb +52 -0
  436. data/lib/contrast/utils/environment_util.rb +152 -0
  437. data/lib/contrast/utils/freeze_util.rb +36 -0
  438. data/lib/contrast/utils/gemfile_reader.rb +191 -0
  439. data/lib/contrast/utils/hash_digest.rb +148 -0
  440. data/lib/contrast/utils/heap_dump_util.rb +113 -0
  441. data/lib/contrast/utils/invalid_configuration_util.rb +88 -0
  442. data/lib/contrast/utils/inventory_util.rb +126 -0
  443. data/lib/contrast/utils/io_util.rb +61 -0
  444. data/lib/contrast/utils/object_share.rb +117 -0
  445. data/lib/contrast/utils/operating_environment.rb +38 -0
  446. data/lib/contrast/utils/os.rb +49 -0
  447. data/lib/contrast/utils/path_util.rb +151 -0
  448. data/lib/contrast/utils/performs_logging.rb +152 -0
  449. data/lib/contrast/utils/preflight_util.rb +13 -0
  450. data/lib/contrast/utils/prevent_serialization.rb +52 -0
  451. data/lib/contrast/utils/rack_assess_session_cookie.rb +104 -0
  452. data/lib/contrast/utils/rails_assess_configuration.rb +95 -0
  453. data/lib/contrast/utils/random_util.rb +22 -0
  454. data/lib/contrast/utils/resource_loader.rb +23 -0
  455. data/lib/contrast/utils/ruby_ast_rewriter.rb +74 -0
  456. data/lib/contrast/utils/scope_util.rb +99 -0
  457. data/lib/contrast/utils/service_response_util.rb +116 -0
  458. data/lib/contrast/utils/service_sender_util.rb +98 -0
  459. data/lib/contrast/utils/sha256_builder.rb +69 -0
  460. data/lib/contrast/utils/sinatra_helper.rb +49 -0
  461. data/lib/contrast/utils/stack_trace_utils.rb +209 -0
  462. data/lib/contrast/utils/string_utils.rb +72 -0
  463. data/lib/contrast/utils/tag_util.rb +139 -0
  464. data/lib/contrast/utils/thread_tracker.rb +54 -0
  465. data/lib/contrast/utils/timer.rb +78 -0
  466. data/resources/assess/policy.json +1673 -0
  467. data/resources/csrf/inject.js +44 -0
  468. data/resources/deadzone/policy.json +55 -0
  469. data/resources/factory-bot-spec/spec_helper.rb +30 -0
  470. data/resources/inventory/policy.json +110 -0
  471. data/resources/protect/policy.json +417 -0
  472. data/resources/rubocops/kernel/catch_cop.rb +37 -0
  473. data/resources/rubocops/kernel/require_cop.rb +37 -0
  474. data/resources/rubocops/kernel/require_relative_cop.rb +33 -0
  475. data/resources/rubocops/module/autoload_cop.rb +37 -0
  476. data/resources/rubocops/module/const_defined_cop.rb +37 -0
  477. data/resources/rubocops/module/const_get_cop.rb +37 -0
  478. data/resources/rubocops/module/const_set_cop.rb +37 -0
  479. data/resources/rubocops/module/constants_cop.rb +37 -0
  480. data/resources/rubocops/module/name_cop.rb +37 -0
  481. data/resources/rubocops/object/class_cop.rb +37 -0
  482. data/resources/rubocops/object/freeze_cop.rb +37 -0
  483. data/resources/rubocops/object/frozen_cop.rb +37 -0
  484. data/resources/rubocops/object/is_a_cop.rb +37 -0
  485. data/resources/rubocops/object/method_cop.rb +37 -0
  486. data/resources/rubocops/object/respond_to_cop.rb +37 -0
  487. data/resources/rubocops/object/singleton_class_cop.rb +37 -0
  488. data/resources/rubocops/regexp/spelling_cop.rb +44 -0
  489. data/resources/rubocops/thread/new_cop.rb +39 -0
  490. data/resources/ruby-spec/ancestors_spec.rb +70 -0
  491. data/resources/ruby-spec/modulo_spec.rb +831 -0
  492. data/resources/ruby-spec/parameters_spec.rb +261 -0
  493. data/resources/ruby-spec/ruby_spec_spec_helper.rb +35 -0
  494. data/resources/test_marker.txt +1 -0
  495. data/ruby-agent.gemspec +129 -0
  496. data/service_executables/.gitkeep +0 -0
  497. data/service_executables/VERSION +1 -0
  498. data/service_executables/linux/contrast-service +0 -0
  499. data/service_executables/mac/contrast-service +0 -0
  500. metadata +945 -0
@@ -0,0 +1,379 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ cs__scoped_require 'contrast/agent/settings_state'
5
+ cs__scoped_require 'contrast/core_extensions/module'
6
+ cs__scoped_require 'contrast/utils/boolean_util'
7
+
8
+ module Contrast
9
+ module Agent
10
+ # This class functions as a way to query the Agent for its current feature
11
+ # set without having to expose other sections of code to the decision tree
12
+ # needed to make that determination.
13
+ class FeatureState < SettingsState
14
+ include Singleton
15
+
16
+ # FeatureState methods are grouped in modules,
17
+ # and these modules are organized roughly in ascending order
18
+ # according to their complexity - where more complex
19
+ # methods call simpler ones.
20
+
21
+ module ConfigWrappers
22
+ # Wrapper to provide convenience for boolean values, allowing for the
23
+ # handling of nil defaults that behave like true and other strange
24
+ # cases.
25
+ module Booleans
26
+ include Contrast::Components::Interface
27
+ access_component :config
28
+
29
+ # Ruby 2.4 does not nicely compare to nil, so we have to include
30
+ # these wrapper methods. RUBY-179 has the task to update this on
31
+ # EOL of 2.4 support
32
+ def false? config
33
+ Contrast::Utils::BooleanUtil.false?(config)
34
+ end
35
+
36
+ def true? config
37
+ Contrast::Utils::BooleanUtil.true?(config)
38
+ end
39
+
40
+ def inventory_enabled?
41
+ !false?(CONFIG.root.inventory.enable)
42
+ end
43
+
44
+ def protect_forcibly_enabled?
45
+ true?(CONFIG.root.protect.enable)
46
+ end
47
+
48
+ def protect_forcibly_disabled?
49
+ false?(CONFIG.root.protect.enable)
50
+ end
51
+
52
+ def assess_forcibly_enabled?
53
+ true?(CONFIG.root.assess.enable)
54
+ end
55
+
56
+ def assess_forcibly_disabled?
57
+ false?(CONFIG.root.assess.enable)
58
+ end
59
+
60
+ def assess_track_frozen_sources?
61
+ !false?(CONFIG.root.agent.ruby.track_frozen_sources)
62
+ end
63
+
64
+ def scan_response?
65
+ true?(CONFIG.root.assess.enable_scan_response)
66
+ end
67
+
68
+ def omit_body?
69
+ true?(CONFIG.root.agent.omit_body)
70
+ end
71
+
72
+ def require_scanning_enabled?
73
+ !false?(CONFIG.root.agent.ruby.require_scan)
74
+ end
75
+
76
+ def heap_dump_enabled?
77
+ true?(CONFIG.root.agent.heap_dump.enable)
78
+ end
79
+
80
+ def service_forcibly_disabled?
81
+ false?(CONFIG.root.agent.start_bundled_service)
82
+ end
83
+
84
+ def report_any_command_execution?
85
+ ctrl = protect_rule_config[Contrast::Agent::Protect::Rule::CmdInjection::NAME]
86
+ true?(ctrl.disable_system_commands)
87
+ end
88
+
89
+ def report_custom_code_sysfile_access?
90
+ ctrl = protect_rule_config[Contrast::Agent::Protect::Rule::PathTraversal::NAME]
91
+ true?(ctrl.detect_custom_code_accessing_system_files)
92
+ end
93
+
94
+ # Determines if the Process we're currently in matches that of the
95
+ # Process in which the FeatureState instance was created.
96
+ # If it doesn't, that indicates the running context is in a new
97
+ # Process.
98
+ # @return [Boolean] if we're in the original Process in which the
99
+ # FeaturesState instance was initialized.
100
+ def in_new_process?
101
+ current_pid = Process.pid
102
+ original_pid = pid
103
+ current_pid != original_pid
104
+ end
105
+ end
106
+
107
+ # Wrapper for configurations regarding assess & protect rules
108
+ module Parameters
109
+ include Contrast::Components::Interface
110
+ access_component :settings, :config
111
+
112
+ def protect_rule_config
113
+ CONFIG.root.protect.rules || []
114
+ end
115
+
116
+ def assess_rule_disabled? name
117
+ assess_disabled_rules.include? name
118
+ end
119
+
120
+ def protect_rule_enabled? rule_id
121
+ protect_rule_mode(rule_id).to_sym != :NO_ACTION
122
+ end
123
+
124
+ def assess_tags
125
+ CONFIG.root.assess&.tags
126
+ end
127
+
128
+ def assess_disabled_rules
129
+ CONFIG.root.assess&.rules&.disabled_rules || SETTINGS.disabled_assess_rules || []
130
+ end
131
+
132
+ def current_session_id
133
+ Contrast::Utils::StringUtils.force_utf8(SETTINGS.session_id)
134
+ end
135
+
136
+ def disabled_agent_rake_tasks
137
+ CONFIG.root.agent.ruby.disabled_agent_rake_tasks
138
+ end
139
+
140
+ def exclusions
141
+ SETTINGS.exclusion_matchers
142
+ end
143
+
144
+ def url_exclusions
145
+ exclusions.select(&:url?)
146
+ end
147
+
148
+ def input_exclusions
149
+ exclusions.select(&:input?)
150
+ end
151
+
152
+ def code_exclusions
153
+ exclusions.select(&:code?)
154
+ end
155
+ end
156
+ end
157
+
158
+ # Wrapper for the Assess & Protect states
159
+ module SettingWrappers
160
+ include Contrast::Components::Interface
161
+ access_component :settings, :config
162
+
163
+ def protect_setting_enabled?
164
+ SETTINGS.protect_state[:enabled]
165
+ end
166
+
167
+ def assess_setting_enabled?
168
+ SETTINGS.assess_state[:enabled]
169
+ end
170
+ end
171
+
172
+ # whether it's connected to the Contrast Service,
173
+ # whether config succeeded,
174
+ # whether writable paths are actually writeable, etc.
175
+ module AgentState
176
+ # Indicates the status of the Agent - initialized & ready - as well as
177
+ # the mode(s) in which it is functioning
178
+ module Operation
179
+ include Contrast::Components::Interface
180
+ access_component :agent
181
+
182
+ # Return true if the agent is ready to protect the application
183
+ def agent_ready?
184
+ AGENT.enabled? && connection_established? && update_received?
185
+ end
186
+
187
+ def protect_enabled?
188
+ return false unless AGENT.enabled?
189
+
190
+ # config overrides if forcibly set
191
+ return false if protect_forcibly_disabled?
192
+ return true if protect_forcibly_enabled?
193
+
194
+ !!protect_setting_enabled?
195
+ end
196
+
197
+ def assess_enabled?
198
+ return false unless AGENT.enabled?
199
+
200
+ # config overrides if forcibly set
201
+ return false if assess_forcibly_disabled?
202
+ return true if assess_forcibly_enabled?
203
+
204
+ !!assess_setting_enabled?
205
+ end
206
+ end
207
+
208
+ # Wrapper for the state of our Service settings and a way to access the
209
+ # Contrast::Agent::SocketClient responsible for interactions between
210
+ # the Agent & Service.
211
+ module Service
212
+ include Contrast::Components::Interface
213
+ access_component :agent
214
+
215
+ def service_enabled?
216
+ AGENT.enabled? && !service_forcibly_disabled?
217
+ end
218
+
219
+ def client
220
+ @_client ||= Contrast::Agent::SocketClient.new
221
+ end
222
+
223
+ # Return true if the agent has connected with the service
224
+ def connection_established?
225
+ client.connection_established?
226
+ end
227
+
228
+ # Return true if the agent has processed a response from the service
229
+ def update_received?
230
+ !@last_update.nil?
231
+ end
232
+ end
233
+ end
234
+
235
+ # 'Controls' synthesize all of the above into parameter sets.
236
+ # These can have more complex logic.
237
+ module Controls
238
+ include Contrast::Components::Interface
239
+ access_component :config
240
+
241
+ def heap_dump_control
242
+ {
243
+ path: File.absolute_path(CONFIG.root.agent.heap_dump.path),
244
+ count: CONFIG.root.agent.heap_dump.count.to_i,
245
+ window: CONFIG.root.agent.heap_dump.window_ms.to_f / 1000,
246
+ delay: CONFIG.root.agent.heap_dump.delay_ms.to_f / 1000,
247
+ clean: true?(CONFIG.root.agent.heap_dump.clean)
248
+ }
249
+ end
250
+
251
+ DEFAULT_SAMPLING_ENABLED = false
252
+ DEFAULT_SAMPLING_BASELINE = 5
253
+ DEFAULT_SAMPLING_REQUEST_FREQUENCY = 5
254
+ DEFAULT_SAMPLING_RESPONSE_FREQUENCY = 25
255
+ DEFAULT_SAMPLING_WINDOW_MS = 180_000 # 3 minutes, arbitrary value from Java agent
256
+ def sampling_control settings = @sampling_features
257
+ cas = CONFIG.root.assess&.sampling
258
+
259
+ {
260
+ enabled: [cas&.enable, settings&.enabled, DEFAULT_SAMPLING_ENABLED] .reject(&:nil?).first,
261
+ baseline: [cas&.baseline, settings&.baseline, DEFAULT_SAMPLING_BASELINE] .map(&:to_i).find(&:positive?),
262
+ request_frequency: [cas&.request_frequency, settings&.request_frequency, DEFAULT_SAMPLING_REQUEST_FREQUENCY] .map(&:to_i).find(&:positive?),
263
+ response_frequency: [cas&.response_frequency, settings&.response_frequency, DEFAULT_SAMPLING_RESPONSE_FREQUENCY].map(&:to_i).find(&:positive?),
264
+ window: [cas&.window_ms, settings&.window_ms, DEFAULT_SAMPLING_WINDOW_MS] .map(&:to_i).find(&:positive?)
265
+ }
266
+ end
267
+
268
+ DEFAULT_LOG_FILENAME = 'contrast_service.log'
269
+ def service_control
270
+ {
271
+ host: CONFIG.root.agent.service.host || Contrast::Configuration::DEFAULT_HOST,
272
+ port: CONFIG.root.agent.service.port || Contrast::Configuration::DEFAULT_PORT,
273
+ socket_path: CONFIG.root.agent.service.socket,
274
+ logger_path: CONFIG.root.agent.service.logger.path || DEFAULT_LOG_FILENAME
275
+ }
276
+ end
277
+
278
+ def exception_control
279
+ {
280
+ enable: true?(CONFIG.root.agent.ruby.exceptions.capture),
281
+ status: CONFIG.root.agent.ruby.exceptions.override_status || 403,
282
+ message: CONFIG.root.agent.ruby.exceptions.override_message || Contrast::Utils::ObjectShare::OVERRIDE_MESSAGE
283
+ }
284
+ end
285
+ end
286
+
287
+ # Wrapper for the state of our diagnostics settings
288
+ module Diagnostic
289
+ include Contrast::Components::Interface
290
+ access_component :config
291
+
292
+ def uninstrument_namespaces
293
+ tmp = CONFIG.root.agent.ruby.uninstrument_namespace.map(&:to_sym)
294
+ tmp.select! { |sym| Object.cs__const_defined?(sym) }
295
+ tmp.map! { |sym| Object.cs__const_get(sym) }
296
+ tmp
297
+ end
298
+ end
299
+
300
+ # Wrapper for the state of our logging settings and holder for utility
301
+ # methods for logging state.
302
+ module Logging
303
+ include Contrast::Components::Interface
304
+ access_component :config
305
+
306
+ FALLBACK = STDOUT
307
+ LOG_INFO_RULE_SETTINGS = 'Current rule settings:'
308
+ # Utility method to log the current mode of all the rules
309
+ def log_rule_modes
310
+ return unless logger&.info?
311
+
312
+ logger.info(LOG_INFO_RULE_SETTINGS)
313
+ PROTECT.rules.each { |k, v| logger.info(".. protect:\t#{ k } (#{ v.mode })") }
314
+ ASSESS.rules.each { |k, v| logger.info(".. assess: \t#{ k } (#{ v.enabled? })") }
315
+ end
316
+
317
+ ENV_KEYS = %w[HOME PWD RACK_ENV RAILS_ENV RUBY_VERSION GEM_HOME GEM_PATH].cs__freeze
318
+ # Utility method to log some current ruby and rails information from environment
319
+ def log_environment
320
+ return unless logger.info?
321
+
322
+ logger.info "AGENT_VERSION=#{ Contrast::Agent::VERSION }"
323
+ ENV.each do |env_key, env_value|
324
+ env_key = env_key.to_s
325
+ next unless ENV_KEYS.include?(env_key) ||
326
+ (env_key.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER) &&
327
+ !env_key.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER + 'API'))
328
+
329
+ logger.info "#{ env_key }=#{ env_value }"
330
+ end
331
+ logger.info "PARENT_PROCESS_ID=#{ Process.ppid }"
332
+ logger.info "PROCESS_ID=#{ Process.pid }"
333
+ end
334
+
335
+ def log_configuration
336
+ return unless logger.info?
337
+
338
+ loggable = CONFIG.raw.send(:load_config)
339
+ loggable.delete('api')
340
+ logger.info "LOCAL CONFIGURATION: #{ JSON.pretty_generate(loggable) }"
341
+ end
342
+
343
+ FRAMEWORKS = %w[rails sinatra grape].cs__freeze
344
+ WEB_SERVERS = %w[agoo falcon hoof iodine mongrel mongrel2 passenger puma rack skinny thin trinidad unicorn webrick yarn].cs__freeze
345
+ LIBRARIES = %w[excon json mongo moped mysql nokogiri oga ox pg psych sqlite3 typhoeus yaml].cs__freeze
346
+ def log_specific_libraries
347
+ FRAMEWORKS.each(&cs__method(:log_gem_data))
348
+ WEB_SERVERS.each(&cs__method(:log_gem_data))
349
+ LIBRARIES.each(&cs__method(:log_gem_data))
350
+ end
351
+
352
+ def log_all_libraries
353
+ return unless logger.debug?
354
+
355
+ Gem.loaded_specs.each_pair do |_name, gem_spec|
356
+ logger.debug { "GEM LOADED: #{ gem_spec.name }=#{ gem_spec.version }" }
357
+ end
358
+ end
359
+
360
+ def log_gem_data gem_name
361
+ gem_spec = Gem.loaded_specs[gem_name]
362
+ return unless gem_spec
363
+
364
+ logger.info { "GEM LOADED: #{ gem_spec.name }=#{ gem_spec.version }" }
365
+ end
366
+ end
367
+
368
+ # Methods that query the config.
369
+ include ConfigWrappers::Booleans # These check boolean config options.
370
+ include ConfigWrappers::Parameters # These check against the config and return parameters.
371
+ include SettingWrappers # Methods that query settings from TeamServer.
372
+ include AgentState::Operation # Enable/disable the agent, ask if the agent can run.
373
+ include AgentState::Service # Agent's client that talks to the service.
374
+ include Controls # Syntheses of the above.
375
+ include Diagnostic # Misc.
376
+ include Logging # Logging.
377
+ end
378
+ end
379
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ cs__scoped_require 'contrast/agent/inventory/policy/trigger_node'
5
+ cs__scoped_require 'contrast/agent/patching/policy/policy'
6
+
7
+ # classes required by patches in the policy
8
+ cs__scoped_require 'contrast/core_extensions/inventory/datastores'
9
+
10
+ module Contrast
11
+ module Agent
12
+ module Inventory
13
+ module Policy
14
+ # This is just a holder for our policy. Takes the policy JSON and
15
+ # converts it into hashes that we can access nicely
16
+ class Policy < Contrast::Agent::Patching::Policy::Policy
17
+ def self.policy_folder
18
+ 'inventory'
19
+ end
20
+
21
+ def disabled_globally?
22
+ !INVENTORY.enabled?
23
+ end
24
+
25
+ def node_type
26
+ Contrast::Agent::Inventory::Policy::TriggerNode
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ cs__scoped_require 'contrast/agent/patching/policy/trigger_node'
5
+
6
+ module Contrast
7
+ module Agent
8
+ module Inventory
9
+ module Policy
10
+ # This class functions to translate our policy.json into an actionable
11
+ # Ruby object, allowing for dynamic patching over hardcoded patching,
12
+ # specifically for those methods which result in the trigger of an
13
+ # event interesting to the design of the application.
14
+ class TriggerNode < Contrast::Agent::Patching::Policy::TriggerNode
15
+ def feature
16
+ 'Inventory'
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,116 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ cs__scoped_require 'logger'
5
+
6
+ cs__scoped_require 'contrast/core_extensions/module'
7
+ cs__scoped_require 'contrast/components/interface'
8
+
9
+ module Contrast
10
+ module Agent
11
+ # This class functions to serve as a wrapper around our logging, as we need
12
+ # to be able to dynamically update level based on updates to TeamServer.
13
+ class LoggerManager
14
+ include Contrast::Components::Interface
15
+ access_component :app_context, :logging, :config
16
+
17
+ DEFAULT_NAME = 'contrast.log'
18
+ DEFAULT_LEVEL = ::Logger::INFO
19
+ VALID_LEVELS = %w[INFO WARN DEBUG FATAL UNKNOWN ERROR].cs__freeze
20
+ STDOUT_STR = 'STDOUT'
21
+ STDERR_STR = 'STDERR'
22
+
23
+ attr_reader :current,
24
+ :previous_path,
25
+ :previous_level
26
+
27
+ def initialize
28
+ update
29
+ rescue StandardError => e
30
+ Contrast::Agent::FeatureState::Logging::FALLBACK.puts 'Unable to initialize regular logger in LoggerManager.'
31
+ Contrast::Agent::FeatureState::Logging::FALLBACK.puts e.backtrace.join(Contrast::Utils::ObjectShare::NEW_LINE)
32
+ end
33
+
34
+ def update log_file = nil, log_level = nil
35
+ config = CONFIG.root.agent.logger
36
+
37
+ config_path = config.path&.length.to_i.positive? ? config.path : nil
38
+ config_level = config.level&.length&.positive? ? config.level : nil
39
+
40
+ # config > settings > default
41
+ path = valid_path(config_path || log_file)
42
+ level_const = valid_level(config_level || log_level)
43
+
44
+ # don't needlessly recreate logger
45
+ return if @current && (path == previous_path) && (level_const == previous_level)
46
+
47
+ @previous_path = path
48
+ @previous_level = level_const
49
+
50
+ @current = build(path: path, level_const: level_const)
51
+
52
+ @current.debug { 'Initialized new contrast agent logger' }
53
+
54
+ self
55
+ rescue StandardError => e
56
+ Contrast::Agent::FeatureState::Logging::FALLBACK.puts 'Unable to process update to LoggerManager.'
57
+ Contrast::Agent::FeatureState::Logging::FALLBACK.puts e.backtrace.join(Contrast::Utils::ObjectShare::NEW_LINE)
58
+ end
59
+
60
+ private
61
+
62
+ def default_progname
63
+ "Contrast #{ APP_CONTEXT.name }"
64
+ end
65
+
66
+ def build path: STDOUT_STR, progname: default_progname, level_const: DEFAULT_LEVEL
67
+ current = case path
68
+ when STDOUT_STR, STDERR_STR
69
+ ::Logger.new(Object.cs__const_get(path))
70
+ else
71
+ ::Logger.new(path)
72
+ end
73
+
74
+ current.progname = progname
75
+ current.level = level_const
76
+
77
+ current.formatter = proc do |severity_f, datetime_f, progname_f, msg_f|
78
+ "#{ datetime_f.strftime('%Y-%m-%d %H:%M:%S,%L') } [#{ progname_f }] #{ severity_f } - #{ msg_f }\n"
79
+ end
80
+
81
+ current
82
+ end
83
+
84
+ def valid_path path
85
+ path = path.nil? ? Contrast::Utils::ObjectShare::EMPTY_STRING : path
86
+ return path if path == STDOUT_STR
87
+ return path if path == STDERR_STR
88
+
89
+ path = DEFAULT_NAME if path.empty?
90
+ if Contrast::Utils::IOUtil.write_permission?(path)
91
+ path
92
+ else
93
+ if File.directory?(path)
94
+ Contrast::Agent::FeatureState::Logging::FALLBACK.puts "Unable to create log in directory: #{ path }. \n Writing to standard out instead"
95
+ else
96
+ Contrast::Agent::FeatureState::Logging::FALLBACK.puts "Unable to write to log file: #{ path } \n Writing to standard out instead"
97
+ end
98
+
99
+ STDOUT_STR
100
+ end
101
+ end
102
+
103
+ def valid_level level
104
+ level = level.nil? ? DEFAULT_LEVEL : level
105
+ level = 'DEBUG' if level == 'TRACE'
106
+ if VALID_LEVELS.include?(level)
107
+ Object.cs__const_get("::Logger::#{ level }")
108
+ else
109
+ DEFAULT_LEVEL
110
+ end
111
+ rescue StandardError
112
+ DEFAULT_LEVEL
113
+ end
114
+ end
115
+ end
116
+ end