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,113 @@
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 'objspace'
5
+ cs__scoped_require 'contrast/components/interface'
6
+
7
+ module Contrast
8
+ module Utils
9
+ # Implementation of a heap dump util to automate generation
10
+ class HeapDumpUtil
11
+ include Contrast::Components::Interface
12
+ access_component :logging, :heap_dump
13
+
14
+ LOG_ERROR_DUMPS = 'Unable to generate heap dumps'
15
+ FILE_WRITE_FLAGS = 'w'
16
+
17
+ class << self
18
+ def run
19
+ return unless heap_dump_enabled?
20
+
21
+ log_enabled_warning
22
+ dir = heap_dump_control[:path]
23
+ Dir.mkdir(dir) unless Dir.exist?(dir)
24
+ return unless File.writable?(dir)
25
+
26
+ delay = heap_dump_control[:delay]
27
+ Contrast::Agent::Thread.new do
28
+ logger.info("HEAP DUMP THREAD INITIALIZED. WAITING #{ delay } SECONDS TO BEGIN.")
29
+ sleep(delay)
30
+ capture_heap_dump
31
+ end
32
+ rescue StandardError => e
33
+ logger.info(LOG_ERROR_DUMPS, e)
34
+ end
35
+
36
+ def log_enabled_warning
37
+ dir = heap_dump_control[:path]
38
+ window = heap_dump_control[:window]
39
+ count = heap_dump_control[:count]
40
+ delay = heap_dump_control[:delay]
41
+ clean = heap_dump_control[:clean]
42
+
43
+ logger.info <<~WARNING
44
+ *****************************************************
45
+ ******** HEAP DUMP HAS BEEN ENABLED ********
46
+ *** APPLICATION PROCESS WILL EXIT UPON COMPLETION ***
47
+ *****************************************************
48
+
49
+ Heap dump is a debugging tool that snapshots the entire
50
+ state of the Ruby VM. It is an exceptionally expensive
51
+ process, and should only be used to debug especially
52
+ pernicious errors.
53
+
54
+ It will write multiple memory snaphots, which are liable
55
+ to be multiple gigabytes in size.
56
+ They will be named "[unix timestamp]-heap.dump",
57
+ e.g.: 1020304050-heap.dump
58
+
59
+ It will then call Ruby `exit()`.
60
+
61
+ If this is not your specific intent, you can (and should)
62
+ disable this option in your Contrast config file.
63
+
64
+ HEAP DUMP PARAMETERS:
65
+ \t[write files to this directory] dir: #{ dir }
66
+ \t[wait this many seconds in between dumps] window: #{ window }
67
+ \t[heap dump this many times] count: #{ count }
68
+ \t[wait this many seconds into app lifetime] delay: #{ delay }
69
+ \t[perform gc pass before dump] clean: #{ clean }
70
+
71
+ *****************************************************
72
+ ******** YOU HAVE BEEN WARNED ********
73
+ *****************************************************
74
+ WARNING
75
+ end
76
+
77
+ def capture_heap_dump
78
+ dir = heap_dump_control[:path]
79
+ window = heap_dump_control[:window]
80
+ count = heap_dump_control[:count]
81
+ clean = heap_dump_control[:clean]
82
+ logger.info(nil, 'HEAP DUMP MAIN LOOP')
83
+ ObjectSpace.trace_object_allocations_start
84
+ count.times do |i|
85
+ logger.info(nil, "STARTING HEAP DUMP PASS #{ i + 1 } OF #{ count }")
86
+ output = "#{ Time.now.to_f }-heap.dump"
87
+ output = File.join(dir, output)
88
+ begin
89
+ logger.info(nil, "OPENING FILE #{ dir }/#{ output } FOR HEAP DUMP")
90
+ file = File.new(output, FILE_WRITE_FLAGS)
91
+ if clean
92
+ logger.info(nil, 'PERFORMING GARBAGE COLLECTION BEFORE HEAP DUMP')
93
+ GC.start
94
+ end
95
+ ObjectSpace.dump_all(output: file)
96
+ logger.info(nil, "FINISHING HEAP DUMP PASS #{ i + 1 } OF #{ count }")
97
+ ensure
98
+ file.close
99
+ end
100
+ sleep(window)
101
+ end
102
+ ensure
103
+ ObjectSpace.trace_object_allocations_stop
104
+ logger.info(nil, '*****************************************************')
105
+ logger.info(nil, '******** HEAP DUMP HAS CONCLUDED ********')
106
+ logger.info(nil, '*** APPLICATION PROCESS WILL EXIT SHORTLY ***')
107
+ logger.info(nil, '*****************************************************')
108
+ exit # We weren't kidding!
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: false
3
+
4
+ cs__scoped_require 'contrast/components/interface'
5
+
6
+ module Contrast
7
+ module Utils
8
+ # This utility allows us to report invalid configurations detected in
9
+ # customer applications, as determined by Configuration Rules at runtime.
10
+ module InvalidConfigurationUtil
11
+ include Contrast::Components::Interface
12
+ access_component :agent, :analysis, :contrast_service, :logging
13
+
14
+ CS__PATH = 'path'.cs__freeze
15
+ CS__SESSION_ID = 'sessionId'.cs__freeze
16
+ CS__SNIPPET = 'snippet'.cs__freeze
17
+
18
+ # Build and report a finding for the given rule
19
+ #
20
+ # @param rule_id [String] the rule that was violated by the configuration
21
+ # @param user_provided_options [Hash] the configuration value(s) which
22
+ # violated the rule
23
+ # @param call_location [Thread::Backtrace::Location] the location where
24
+ # the bad configuration was set
25
+ def cs__report_finding rule_id, user_provided_options, call_location
26
+ finding = Contrast::Api::Dtm::Finding.new
27
+ finding.rule_id = rule_id
28
+ path = call_location.path
29
+ # just get the file name, not the full path
30
+ path = path.split(Contrast::Utils::ObjectShare::SLASH).last
31
+ session_id = user_provided_options[:key].to_s if user_provided_options
32
+
33
+ finding.version = Contrast::Agent::Assess::Policy::TriggerMethod::CURRENT_FINDING_VERSION
34
+ finding.properties[CS__SESSION_ID] = Contrast::Utils::StringUtils.force_utf8(session_id)
35
+ finding.properties[CS__PATH] = Contrast::Utils::StringUtils.force_utf8(path)
36
+ file_path = call_location.absolute_path
37
+ snippet = file_snippet(file_path, call_location)
38
+ finding.properties[CS__SNIPPET] = Contrast::Utils::StringUtils.force_utf8(snippet)
39
+
40
+ hash = Contrast::Utils::HashDigest.generate_config_hash(finding)
41
+ finding.hash_code = Contrast::Utils::StringUtils.force_utf8(hash)
42
+ finding.preflight = Contrast::Utils::PreflightUtil.create_preflight(finding)
43
+
44
+ activity = Contrast::Api::Dtm::Activity.new
45
+ activity.findings << finding
46
+
47
+ # If assess is enabled, we can just send the activity
48
+ if ASSESS.enabled?
49
+ build_tags(activity)
50
+ CONTRAST_SERVICE.queue_message activity
51
+ # Otherwise, if the Agent isn't ready, we have to queue the messages
52
+ # until we know the starting state.
53
+ else
54
+ Contrast::Utils::ServiceSenderUtil.add_to_assess_messages activity
55
+ end
56
+ rescue StandardError => e
57
+ logger.error(e, "Unable to build a finding for #{ rule_id }")
58
+ end
59
+
60
+ private
61
+
62
+ # This seems silly to pull out, but we can ONLY call this in the case
63
+ # where we have a configuration. Doing otherwise results in a bad error
64
+ # case where we try to do other things, like logging, which behave
65
+ # strangely without a config
66
+ def build_tags activity
67
+ activity.finding_tags = Contrast::Utils::StringUtils.force_utf8(ASSESS.tags)
68
+ end
69
+
70
+ def file_snippet file_path, call_location
71
+ idx = call_location&.lineno
72
+ if file_path && idx && File.exist?(file_path)
73
+ idx = idx > 5 ? idx - 5 : 0
74
+ snippet = ''
75
+ File.foreach(file_path).with_index do |line, line_num|
76
+ next unless line_num >= idx
77
+ break if line_num > idx + 10
78
+
79
+ snippet << line
80
+ snippet << Contrast::Utils::ObjectShare::NEW_LINE
81
+ end
82
+ return snippet
83
+ end
84
+ call_location&.label&.dup
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,126 @@
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/utils/timer'
5
+ cs__scoped_require 'contrast/utils/object_share'
6
+ cs__scoped_require 'contrast/utils/gemfile_reader'
7
+ cs__scoped_require 'contrast/components/interface'
8
+
9
+ module Contrast
10
+ module Utils
11
+ # Utilities for getting inventory information from the application
12
+ class InventoryUtil
13
+ include Contrast::Components::Interface
14
+ access_component :logging
15
+
16
+ # TeamServer only accepts certain values for ArchitectureComponents.
17
+ # DO NOT CHANGE THIS!
18
+ AC_TYPE_DB = 'db'
19
+ # TeamServer only accepts certain values for FlowMap Services.
20
+ # DO NOT CHANGE THIS
21
+ DATABASE = 'Database'
22
+ ADAPTER = 'adapter'
23
+ HOST = 'host'
24
+ PORT = 'port'
25
+ DATABASE_LOWER = 'database'
26
+ DEFAULT = 'default'
27
+ LOCALHOST = 'localhost'
28
+
29
+ def self.inventory_class class_path
30
+ Contrast::Utils::GemfileReader.instance.map_class(class_path)
31
+ rescue StandardError => e
32
+ logger.error(e, "Unable to inventory #{ class_path }")
33
+ end
34
+
35
+ def self.active_record_config
36
+ return @_active_record_config if instance_variable_defined?(:@_active_record_config)
37
+
38
+ @_active_record_config = ActiveRecord::Base.connection_config rescue nil # rubocop:disable Style/RescueModifier
39
+ end
40
+
41
+ def self.append_db_config activity_or_update, hash_or_str = Contrast::Utils::InventoryUtil.active_record_config
42
+ arr = build_from_db_config(hash_or_str)
43
+ return unless arr&.any?
44
+
45
+ activity_or_update.technologies[DATABASE] = true
46
+ arr.each do |a|
47
+ next unless a
48
+
49
+ if activity_or_update.is_a?(Contrast::Api::Dtm::Activity)
50
+ activity_or_update.architectures << a
51
+ else
52
+ activity_or_update.components << a
53
+ end
54
+ next if a.vendor.empty?
55
+
56
+ activity_or_update.technologies[a.vendor] = true
57
+ end
58
+ rescue StandardError => e
59
+ logger.error(e, 'Unable to append db config')
60
+ nil
61
+ end
62
+
63
+ def self.build_from_db_config hash_or_str
64
+ return unless hash_or_str
65
+
66
+ if hash_or_str.is_a?(Hash)
67
+ build_from_db_hash(hash_or_str)
68
+ else
69
+ build_from_db_string(hash_or_str.to_s)
70
+ end
71
+ end
72
+
73
+ def self.build_from_db_hash hash
74
+ ac = Contrast::Api::Dtm::ArchitectureComponent.new
75
+ ac.vendor = hash[:adapter] || hash[ADAPTER] || Contrast::Utils::ObjectShare::EMPTY_STRING
76
+ ac.remote_host = host_from_hash(hash)
77
+ ac.remote_port = port_from_hash(hash)
78
+ ac.type = AC_TYPE_DB
79
+ ac.url = hash[:database] || hash[DATABASE_LOWER] || DEFAULT
80
+ [ac]
81
+ end
82
+
83
+ def self.host_from_hash hash
84
+ hash[:host] || hash[HOST] || Contrast::Utils::ObjectShare::EMPTY_STRING
85
+ end
86
+
87
+ def self.port_from_hash hash
88
+ p = hash[:port] || hash[PORT] || Contrast::Utils::ObjectShare::EMPTY_STRING
89
+ p.to_i
90
+ end
91
+
92
+ # Examples:
93
+ # mongodb://[user:pass@]host1[:port1][,host2[:port2],[,hostN[:portN]]][/[database][?options]]
94
+ # postgresql://scott:tiger@localhost/mydatabase
95
+ # mysql+mysqlconnector://scott:tiger@localhost/foo
96
+ def self.build_from_db_string str
97
+ adapter, hosts, database = split_connection_str(str)
98
+ acs = []
99
+ hosts.split(Contrast::Utils::ObjectShare::COMMA).map do |s|
100
+ host, port = s.split(Contrast::Utils::ObjectShare::COLON)
101
+
102
+ ac = Contrast::Api::Dtm::ArchitectureComponent.new
103
+ ac.vendor = Contrast::Utils::StringUtils.force_utf8(adapter)
104
+ ac.remote_host = Contrast::Utils::StringUtils.force_utf8(host)
105
+ ac.remote_port = port.to_i
106
+ ac.type = AC_TYPE_DB
107
+ ac.url = Contrast::Utils::StringUtils.force_utf8(database)
108
+ acs << ac
109
+ end
110
+ acs
111
+ end
112
+
113
+ def self.split_connection_str str
114
+ adapter, str = str.split(Contrast::Utils::ObjectShare::COLON_SLASH_SLASH)
115
+ _auth, str = str.split(Contrast::Utils::ObjectShare::AT)
116
+ # Not currently used
117
+ # user, pass = auth.split(Contrast::Utils::ObjectShare::COLON)
118
+ hosts, db_and_options = str.split(Contrast::Utils::ObjectShare::SLASH)
119
+ hosts << LOCALHOST if hosts.empty?
120
+ database, _options = db_and_options.split(Contrast::Utils::ObjectShare::QUESTION_MARK)
121
+
122
+ [adapter, hosts, database]
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,61 @@
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/components/interface'
5
+
6
+ module Contrast
7
+ module Utils
8
+ # Util for information about an IO
9
+ class IOUtil
10
+ include Contrast::Components::Interface
11
+
12
+ access_component :logging
13
+
14
+ # StringIO is a valid path because it logs directly to a string buffer
15
+ def self.write_permission? path
16
+ return false if path.nil?
17
+ return true if path.is_a?(StringIO)
18
+ return File.writable?(path) if File.exist?(path)
19
+
20
+ dir_name = File.dirname(File.absolute_path(path))
21
+ File.writable?(dir_name)
22
+ end
23
+
24
+ # We're only going to call rewind on things that we believe are safe to
25
+ # call it on. This method white lists those cases and returns false in
26
+ # all others.
27
+ def self.should_rewind? potential_io
28
+ return true if potential_io.is_a?(StringIO)
29
+ return false unless io?(potential_io)
30
+
31
+ should_rewind_io?(potential_io)
32
+ rescue StandardError => e
33
+ logger.debug(e, "Encountered an issue inspecting instance of #{ potential_io } - continuing without rewind")
34
+ false
35
+ end
36
+
37
+ # IO cannot be used with streams such as pipes, ttys, and sockets.
38
+ def self.should_rewind_io? io
39
+ return false if io.tty?
40
+
41
+ status = io.stat
42
+ return false unless status
43
+ return false if status.pipe?
44
+ return false if status.socket?
45
+
46
+ true
47
+ end
48
+
49
+ # A class is IO if it is a decedent or delegate of IO
50
+ def self.io? object
51
+ return true if object.is_a?(IO)
52
+
53
+ # DelegateClass, which is a Delegator, defines __getobj__ as a way to
54
+ # get the object that the class wraps around (delegates to)
55
+ return false unless object.is_a?(Delegator)
56
+
57
+ object.__getobj__.is_a?(IO)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,117 @@
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
+ # rubocop:disable Object/Freeze
5
+ module Contrast
6
+ module Utils
7
+ # A utility class where a series of commonly used Strings and other
8
+ # commonly used objects can be store and frozen to prevent unnecessary
9
+ # duplication.
10
+ class ObjectShare
11
+ # Strings
12
+ AND = '&'
13
+ OR = '||'
14
+ PIPE = '|'
15
+ ASTERISK = '*'
16
+ BACK_SLASH = '\\'
17
+ EMPTY_STRING = ''
18
+ COLON = ':'
19
+ COMMA = ','
20
+ DASH = '-'
21
+ DOUBLE_QUOTE = '"'
22
+ EQUALS = '='
23
+ EXCLAMATION = '!'
24
+ HTTP_SCORE = 'HTTP_'
25
+ HTTP_START = 'http:'
26
+ HTTPS_START = 'https:'
27
+ NEW_LINE = "\n"
28
+ NIL_STRING = 'nil'
29
+ PERIOD = '.'
30
+ PLUS_SIGN = '+'
31
+ POUND_SIGN = HASH_CHAR = '#'
32
+ QUESTION_MARK = '?'
33
+ RETURN = "\r"
34
+ SEMICOLON = ';'
35
+ SINGLE_QUOTE = '\''
36
+ SLASH = '/'
37
+ SPACE = ' '
38
+ UNDERSCORE = '_'
39
+ DOUBLE_UNDERSCORE = '__'
40
+ AT = '@'
41
+ LEFT_ANGLE = '<'
42
+ RIGHT_ANGLE = '>'
43
+ LEFT_BRACKET = '['
44
+ RIGHT_BRACKET = ']'
45
+ LEFT_PAREN = '('
46
+ RIGHT_PAREN = ')'
47
+ COLON_SLASH_SLASH = '://'
48
+ TICK = '`'
49
+ BACK_TICK = '`'
50
+ LEFT_CURLY = '{'
51
+ RIGHT_CURLY = '}'
52
+ DOLLAR_SIGN = '$'
53
+ CARROT = '^'
54
+ PERCENT = '%'
55
+ LETTER_Q = 'Q'
56
+ OR_STRING = 'or'
57
+
58
+ DOUBLE_QUOTE_ESCAPED = '&quot;'
59
+
60
+ READ_FLAG = 'r'
61
+ WRITE_FLAG = 'w'
62
+ READ_WRITE_FLAG = 'rw'
63
+
64
+ PARENT_PATH = '..'
65
+
66
+ RUBY = 'Ruby'
67
+ CACHE = 'cache'
68
+ GEM_SUFFIX = '.gem'
69
+
70
+ CONTRAST_METHOD_START = 'cs__'
71
+ CONTRAST_PATCHED_METHOD_START = 'cs__patched_'
72
+ CONTRAST_MODULE_START = 'Contrast::'
73
+ ANONYMOUS_CLASS_MARKER = '#<'
74
+ DOUBLE_COLON = '::'
75
+
76
+ EMPTY_ARRAY = [].freeze
77
+ EMPTY_HASH = {}.freeze
78
+ EMPTY_TRIPLE = [EMPTY_STRING, EMPTY_STRING, EMPTY_STRING].freeze
79
+
80
+ # RegExps
81
+ DIGIT_REGEXP = /[[:digit:]]/.freeze
82
+ WHITE_SPACE_REGEXP = /\s/.freeze
83
+ NOT_WHITE_SPACE_REGEXP = /[^\s]/.freeze
84
+ WINDOWS_REGEXP = /cygwin|mswin|mingw|bccwin|wince|emx/.freeze
85
+
86
+ # Messages
87
+ OVERRIDE_MESSAGE = 'A security filter prevented original response from being returned.'
88
+
89
+ # Configs
90
+ TRUE = 'true'
91
+ FALSE = 'false'
92
+
93
+ CLASS = 'Class'
94
+ MODULE = 'Module'
95
+
96
+ BRACKET_INTERPOLATION_START = '#{'
97
+
98
+ OBJECT_KEY = 'O'
99
+ PARAMETER_KEY = 'P'
100
+ RETURN_KEY = 'R'
101
+ UNKNOWN = 'unknown'
102
+
103
+ INDEX = 'index'
104
+
105
+ VERSION_2_5_0 = '2.5.0'
106
+ VERSION_2_4_2 = '2.4.2'
107
+ VERSION_2_4_1 = '2.4.1'
108
+ VERSION_2_4_0 = '2.4.0'
109
+ VERSION_2_3_5 = '2.3.5'
110
+ VERSION_2_3_4 = '2.3.4'
111
+ VERSION_2_3_0 = '2.3.0'
112
+ VERSION_2_0_4 = '2.0.4'
113
+ VERSION_2_0_0 = '2.0.0'
114
+ end
115
+ end
116
+ end
117
+ # rubocop:enable Object/Freeze