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,34 @@
1
+ #include <funchook.h>
2
+ #include <ruby.h>
3
+
4
+ static VALUE rb_sym_next;
5
+ static VALUE fiber_class;
6
+ static VALUE track_rb_fiber_new;
7
+ static VALUE track_rb_fiber_yield;
8
+
9
+ VALUE rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj);
10
+ VALUE *(*rb_fiber_new_original)(VALUE (*func)(ANYARGS), VALUE obj);
11
+
12
+ VALUE rb_fiber_yield(int argc, const VALUE *argv);
13
+ VALUE *(*rb_fiber_yield_original)(int argc, const VALUE *argv);
14
+
15
+ /* If you call `#next` on an enumerator object, that enumerator object
16
+ * instantiates a fiber and runs its given proc inside of that fiber.
17
+ * This minor design consideration presents a few significant edge-cases to us.
18
+ * - match data from regex is bound to execution context, and it's an open
19
+ * question (but looking grim) as to whether we can propagate at that event.
20
+ * Ruby doesn't expose much around ECs, so both finding an event to hook
21
+ * and having a native way to access the EC data are onerous.
22
+ * - fiber_yield is implemented with jmps in YARV, so our primary paradigm
23
+ * of operating on intercepted return values is off the table.
24
+ * (And heaven help you if you execute `#next` within an rb_protect call.)
25
+ * Luckily, we can read the fiber's return value before it executes a jump,
26
+ * so we have a point at which we can reliably propagate.
27
+ */
28
+ VALUE rb_fiber_new_hook(VALUE (*func)(ANYARGS), VALUE obj);
29
+
30
+ VALUE rb_fiber_yield_hook(int argc, const VALUE *argv);
31
+
32
+ static int install_fiber_hooks();
33
+
34
+ void Init_cs__assess_fiber_track(void);
@@ -0,0 +1,2 @@
1
+ $TO_MAKE = File.basename(__dir__)
2
+ require_relative '../extconf_common'
@@ -0,0 +1,64 @@
1
+ /* Copyright (c) 2020 Contrast Security, Inc. See
2
+ * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
+
4
+ #include "cs__assess_hash.h"
5
+ #include "../cs__common/cs__common.h"
6
+ #include <ruby.h>
7
+
8
+ static VALUE contrast_assess_hash_bracket_get(const int argc, VALUE *argv,
9
+ const VALUE hash) {
10
+ VALUE result;
11
+
12
+ /* Array of Arrays: Hash[ [ [key, value], ... ] ] -> new_hash */
13
+ if (RB_TYPE_P(argv[0], T_ARRAY)) {
14
+ int i;
15
+ for (i = 0; i < argc; i++) {
16
+ argv[i] =
17
+ rb_funcall(hash, rb_sym_assess_hash_dup_and_freeze, 1, argv[i]);
18
+ }
19
+ /* Hash[ key, value, ... ] -> new_hash */
20
+ } else if (argc > 1) {
21
+ int i;
22
+ for (i = 0; i < argc; i += 2) {
23
+ argv[i] =
24
+ rb_funcall(hash, rb_sym_assess_hash_dup_and_freeze, 1, argv[i]);
25
+ }
26
+ }
27
+
28
+ /* unhandled case - shouldn't need it since issue is only unfrozen
29
+ * String keys
30
+ * # Hash[ object ] -> new_hash
31
+ */
32
+ result = rb_funcall2(hash, rb_sym_assess_hash_brackets, argc, argv);
33
+
34
+ return result;
35
+ }
36
+
37
+ static VALUE contrast_assess_hash_bracket_set(const int argc, VALUE *argv,
38
+ const VALUE hash) {
39
+ VALUE result;
40
+ VALUE key;
41
+
42
+ key = rb_funcall2(hash, rb_sym_assess_hash_bracket_set, argc, argv);
43
+ argv[0] = key;
44
+ result = rb_funcall2(hash, rb_sym_assess_hash_bracket_equals, argc, argv);
45
+
46
+ return result;
47
+ }
48
+
49
+ void Init_cs__assess_hash(void) {
50
+ rb_sym_assess_hash_dup_and_freeze = rb_intern("cs__duplicate_and_freeze");
51
+ rb_sym_assess_hash_brackets = rb_intern("cs__patched_[]");
52
+ rb_sym_assess_hash_bracket_set = rb_intern("cs__bracket_set");
53
+ rb_sym_assess_hash_bracket_equals = rb_intern("cs__patched_[]=");
54
+
55
+ VALUE hash_class = rb_define_class("Hash", rb_cObject);
56
+ array_class = rb_define_class("Array", rb_cObject);
57
+
58
+ VALUE singleton = rb_singleton_class(hash_class);
59
+ contrast_alias_method(singleton, "cs__patched_[]", "[]");
60
+ rb_define_method(singleton, "[]", contrast_assess_hash_bracket_get, -1);
61
+
62
+ contrast_alias_method(hash_class, "cs__patched_[]=", "[]=");
63
+ rb_define_method(hash_class, "[]=", contrast_assess_hash_bracket_set, -1);
64
+ }
@@ -0,0 +1,24 @@
1
+ #include <ruby.h>
2
+
3
+ static VALUE array_class;
4
+
5
+ static VALUE rb_sym_assess_hash_dup_and_freeze;
6
+ static VALUE rb_sym_assess_hash_brackets;
7
+ static VALUE rb_sym_assess_hash_bracket_set;
8
+ static VALUE rb_sym_assess_hash_bracket_equals;
9
+
10
+ /*
11
+ * Monkeypatch Ruby Hash with Contrast Security Hash in order ot avoid losing
12
+ * tracking across Strings. Hashes, when given unfrozen Strings as keys,
13
+ * replace these Strings with a frozen copy in the hash. This copy is done is C
14
+ * and does not take into account the tag properties we've provided. Freezing
15
+ * ahead of time should avoid this, similar to the behavior of the -@ Strings
16
+ * -HM
17
+ */
18
+ static VALUE contrast_assess_hash_bracket_get(const int argc, VALUE *argv,
19
+ const VALUE hash);
20
+
21
+ static VALUE contrast_assess_hash_bracket_set(const int argc, VALUE *argv,
22
+ const VALUE hash);
23
+
24
+ void Init_cs__assess_hash(void);
@@ -0,0 +1,2 @@
1
+ $TO_MAKE = File.basename(__dir__)
2
+ require_relative '../extconf_common'
@@ -0,0 +1,36 @@
1
+ /* Copyright (c) 2020 Contrast Security, Inc. See
2
+ * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
+
4
+ #include "cs__assess_kernel.h"
5
+ #include "../cs__common/cs__common.h"
6
+ #include <ruby.h>
7
+
8
+ VALUE
9
+ contrast_patched_kernel_exec(const int argc, const VALUE *argv,
10
+ const VALUE self) {
11
+ int nested_scope =
12
+ RTEST(rb_funcall(contrast_patcher(), rb_sym_in_scope, 0));
13
+
14
+ if (!nested_scope && argc > 0) {
15
+ rb_funcall(contrast_patcher(), rb_sym_enter_scope, 0);
16
+ VALUE data = argv[0];
17
+ rb_funcall(kernel_propagator, exec_apply_trigger, 1, data);
18
+ rb_funcall(contrast_patcher(), rb_sym_exit_scope, 0);
19
+ }
20
+
21
+ return rb_funcall(self, rb_intern("cs__assess_kernel_exec"), argc, *argv);
22
+ }
23
+
24
+ void Init_cs__assess_kernel(void) {
25
+ kernel_propagator = rb_define_module("KernelPropagator");
26
+ exec_apply_trigger = rb_intern("apply_trigger");
27
+
28
+ VALUE singleton = rb_singleton_class(rb_mKernel);
29
+
30
+ contrast_alias_method(rb_mKernel, "cs__assess_kernel_exec", "exec");
31
+ rb_define_private_method(rb_mKernel, "exec", contrast_patched_kernel_exec,
32
+ -1);
33
+
34
+ contrast_alias_method(singleton, "cs__assess_kernel_exec", "exec");
35
+ rb_define_method(singleton, "exec", contrast_patched_kernel_exec, -1);
36
+ }
@@ -0,0 +1,10 @@
1
+ #include <ruby.h>
2
+
3
+ static VALUE exec_apply_trigger;
4
+ static VALUE kernel_propagator;
5
+
6
+ VALUE
7
+ contrast_patched_kernel_exec(const int argc, const VALUE *argv,
8
+ const VALUE self);
9
+
10
+ void Init_cs__assess_kernel(void);
@@ -0,0 +1,2 @@
1
+ $TO_MAKE = File.basename(__dir__)
2
+ require_relative '../extconf_common'
@@ -0,0 +1,47 @@
1
+ /* Copyright (c) 2020 Contrast Security, Inc. See
2
+ * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
+
4
+ #include "cs__assess_marshal_module.h"
5
+ #include "../cs__common/cs__common.h"
6
+ #include <ruby.h>
7
+
8
+ static VALUE contrast_assess_marshal_module_load(const int argc,
9
+ const VALUE *argv) {
10
+ VALUE result;
11
+ VALUE source_string;
12
+
13
+ result = rb_call_super(argc, argv);
14
+
15
+ if (argc >= 1) {
16
+ source_string = argv[0];
17
+
18
+ if (rb_respond_to(source_string, rb_sym_cs_tracked)) {
19
+ VALUE tracked = rb_funcall(source_string, rb_sym_cs_tracked, 0);
20
+
21
+ if (tracked == Qtrue) {
22
+ VALUE skip = rb_funcall(contrast_patcher(),
23
+ rb_sym_skip_assess_analysis, 0);
24
+
25
+ if (skip == Qfalse) {
26
+ VALUE scope =
27
+ rb_funcall(contrast_patcher(), rb_sym_enter_scope, 0);
28
+ rb_funcall(marshal_module, rb_sym_assess_load_trigger_check,
29
+ 2, source_string, result);
30
+ rb_funcall(contrast_patcher(), rb_sym_exit_scope, 1, scope);
31
+ }
32
+ }
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+
38
+ void Init_cs__assess_marshal_module(void) {
39
+ rb_sym_assess_load_trigger_check = rb_intern("cs__load_trigger_check");
40
+
41
+ marshal_module = rb_define_module("Marshal");
42
+
43
+ VALUE contrast_marshal = rb_define_module("MarshalWithContrastAssess");
44
+ rb_define_method(contrast_marshal, "load",
45
+ contrast_assess_marshal_module_load, -1);
46
+ rb_prepend_module(rb_singleton_class(marshal_module), contrast_marshal);
47
+ }
@@ -0,0 +1,18 @@
1
+ #include <ruby.h>
2
+
3
+ static VALUE marshal_module;
4
+
5
+ static VALUE rb_sym_assess_load_trigger_check;
6
+
7
+ /*
8
+ * Rails is a jerk. In Rails 5, they decided to do away with the alias chaining
9
+ * approach in favor of the prepend approach. While we'll need to add long term
10
+ * support for prepend, so far, the only method that we've found that is used
11
+ * regularly by Rails / that is constantly prepended is Marshal.load. We'll
12
+ * special case this for now.
13
+ * -HM (shamelessly commenting on DP's work)
14
+ */
15
+ static VALUE contrast_assess_marshal_module_load(const int argc,
16
+ const VALUE *argv);
17
+
18
+ void Init_cs__assess_marshal_module(void);
@@ -0,0 +1,2 @@
1
+ $TO_MAKE = File.basename(__dir__)
2
+ require_relative '../extconf_common'
@@ -0,0 +1,78 @@
1
+ /* Copyright (c) 2020 Contrast Security, Inc. See
2
+ * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
+
4
+ #include "cs__assess_module.h"
5
+ #include "../cs__common/cs__common.h"
6
+ #include <ruby.h>
7
+
8
+ void contrast_assess_eval_trigger_check(VALUE module, VALUE source, VALUE ret) {
9
+ VALUE has_trigger_check = rb_respond_to(module, trigger_check_method);
10
+
11
+ if (RTEST(
12
+ rb_funcall(contrast_patcher(), rb_sym_skip_contrast_analysis, 0))) {
13
+ return;
14
+ }
15
+
16
+ int nested_scope =
17
+ RTEST(rb_funcall(contrast_patcher(), rb_sym_in_scope, 0));
18
+
19
+ rb_funcall(contrast_patcher(), rb_sym_enter_scope, 0);
20
+
21
+ if (!nested_scope && has_trigger_check) {
22
+ VALUE method = rb_funcall(rb_mKernel, rb_sym_method, 0);
23
+ /* If this method ever throws an exception, the scope-leave
24
+ * needs to be moved within a rescue call.
25
+ */
26
+ rb_funcall(module, trigger_check_method, 3, source, ret, method);
27
+ }
28
+
29
+ rb_funcall(contrast_patcher(), rb_sym_exit_scope, 0);
30
+ }
31
+
32
+ VALUE
33
+ contrast_assess_module_class_eval(const int argc, const VALUE *argv,
34
+ const VALUE mod) {
35
+ VALUE ret = rb_mod_module_eval(argc, argv, mod);
36
+
37
+ if (argc > 0) {
38
+ VALUE data = argv[0];
39
+ contrast_assess_eval_trigger_check(mod, data, ret);
40
+ }
41
+ rb_funcall(assess_patcher, rb_sym_assess_patch_eval, 1, mod);
42
+
43
+ return ret;
44
+ }
45
+
46
+ VALUE
47
+ contrast_assess_module_module_eval(const int argc, const VALUE *argv,
48
+ const VALUE mod) {
49
+ VALUE ret = rb_mod_module_eval(argc, argv, mod);
50
+
51
+ if (argc > 0) {
52
+ VALUE data = argv[0];
53
+ contrast_assess_eval_trigger_check(mod, data, ret);
54
+ }
55
+
56
+ rb_funcall(assess_patcher, rb_sym_assess_patch_eval, 1, mod);
57
+
58
+ return ret;
59
+ }
60
+
61
+ void Init_cs__assess_module(void) {
62
+ rb_sym_assess_patch_eval = rb_intern("patch_assess_on_eval");
63
+
64
+ VALUE assess_policy = rb_define_module_under(assess, "Policy");
65
+ assess_patcher = rb_define_module_under(assess_policy, "Patcher");
66
+
67
+ trigger_check_method = rb_intern("eval_trigger_check");
68
+
69
+ contrast_alias_method(rb_cModule, "cs__patched_class_eval", "class_eval");
70
+
71
+ rb_define_method(rb_cModule, "class_eval",
72
+ contrast_assess_module_class_eval, -1);
73
+
74
+ contrast_alias_method(rb_cModule, "cs__patched_module_eval", "module_eval");
75
+
76
+ rb_define_method(rb_cModule, "module_eval",
77
+ contrast_assess_module_module_eval, -1);
78
+ }
@@ -0,0 +1,25 @@
1
+ #include <ruby.h>
2
+
3
+ /* Contrast::Agent::Assess::Policy::Patcher */
4
+ static VALUE assess_patcher;
5
+
6
+ static VALUE rb_sym_assess_patch_eval;
7
+ static VALUE trigger_check_method;
8
+
9
+ /* c.f. cs__assess_basic_object.c for more context on how eval is patched. */
10
+ void contrast_assess_eval_trigger_check(VALUE module, VALUE source, VALUE ret);
11
+
12
+ /*
13
+ * rb_mod_module_eval is the C method equivalent of Module.class_eval and
14
+ * Module.module_eval. Calling it like this maintains the Ruby method scope
15
+ * that rb_mod_module_eval expects.
16
+ */
17
+ VALUE
18
+ contrast_assess_module_class_eval(const int argc, const VALUE *argv,
19
+ const VALUE mod);
20
+
21
+ VALUE
22
+ contrast_assess_module_module_eval(const int argc, const VALUE *argv,
23
+ const VALUE mod);
24
+
25
+ void Init_cs__assess_module(void);
@@ -0,0 +1,2 @@
1
+ $TO_MAKE = File.basename(__dir__)
2
+ require_relative '../extconf_common'
@@ -0,0 +1,48 @@
1
+ /* Copyright (c) 2020 Contrast Security, Inc. See
2
+ * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
+
4
+ #include "cs__assess_regexp.h"
5
+ #include <ruby.h>
6
+
7
+ void contrast_alias_method(const VALUE target, const char *to,
8
+ const char *from);
9
+
10
+ static VALUE contrast_assess_regexp_equal_squiggle(const int argc,
11
+ const VALUE *argv,
12
+ const VALUE regexp) {
13
+ VALUE result, infohash;
14
+
15
+ result =
16
+ rb_funcall2(regexp, rb_sym_assess_regexp_equal_squiggle, argc, argv);
17
+
18
+ if (RTEST(result)) {
19
+ infohash = rb_hash_new();
20
+ rb_hash_aset(infohash, rb_sym_regexp, regexp);
21
+ rb_hash_aset(infohash, rb_sym_result, result);
22
+ rb_hash_aset(infohash, rb_sym_string, argv[0]);
23
+ rb_hash_aset(infohash, rb_sym_back_ref, rb_backref_get());
24
+ rb_funcall(regexp, rb_sym_assess_track_regexp, 1, infohash);
25
+ }
26
+
27
+ return result;
28
+ }
29
+
30
+ void Init_cs__assess_regexp(void) {
31
+ rb_sym_assess_regexp_equal_squiggle =
32
+ rb_intern("cs__patched_equal_squiggle");
33
+ rb_sym_assess_track_regexp = rb_intern("cs__regexp_tagger");
34
+
35
+ rb_sym_result = ID2SYM(rb_intern("result"));
36
+ rb_global_variable(&rb_sym_result);
37
+ rb_sym_regexp = ID2SYM(rb_intern("regexp"));
38
+ rb_global_variable(&rb_sym_regexp);
39
+ rb_sym_string = ID2SYM(rb_intern("string"));
40
+ rb_global_variable(&rb_sym_string);
41
+ rb_sym_back_ref = ID2SYM(rb_intern("back_ref"));
42
+ rb_global_variable(&rb_sym_back_ref);
43
+
44
+ VALUE regexp_class = rb_define_class("Regexp", rb_cObject);
45
+ contrast_alias_method(regexp_class, "cs__patched_equal_squiggle", "=~");
46
+ rb_define_method(regexp_class, "=~", contrast_assess_regexp_equal_squiggle,
47
+ -1);
48
+ }
@@ -0,0 +1,22 @@
1
+ #include <ruby.h>
2
+
3
+ static VALUE rb_sym_result;
4
+ static VALUE rb_sym_regexp;
5
+ static VALUE rb_sym_string;
6
+ static VALUE rb_sym_back_ref;
7
+ static VALUE rb_sym_assess_regexp_equal_squiggle;
8
+ static VALUE rb_sym_assess_track_regexp;
9
+
10
+ /*
11
+ * argc - number of arguments
12
+ * argv - array of arguments, can be:
13
+ * [nil]
14
+ * [Symbol]
15
+ * [String]
16
+ * regex - reference to self object
17
+ */
18
+ static VALUE contrast_assess_regexp_equal_squiggle(const int argc,
19
+ const VALUE *argv,
20
+ const VALUE regexp);
21
+
22
+ void Init_cs__assess_regexp(void);
@@ -0,0 +1,2 @@
1
+ $TO_MAKE = File.basename(__dir__)
2
+ require_relative '../extconf_common'
@@ -0,0 +1,63 @@
1
+ /* Copyright (c) 2020 Contrast Security, Inc. See
2
+ * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
+
4
+ #include "cs__assess_regexp_track.h"
5
+ #include <funchook.h>
6
+ #include <ruby.h>
7
+
8
+ static VALUE rb_reg_match_pre_hook(VALUE match) {
9
+ VALUE result = rb_reg_match_pre_original(match);
10
+ result = rb_funcall(regexp_class, track_rb_pre_match, 2, match, result);
11
+ return result;
12
+ }
13
+
14
+ static VALUE rb_reg_match_post_hook(VALUE match) {
15
+ VALUE result = rb_reg_match_post_original(match);
16
+ result = rb_funcall(regexp_class, track_rb_post_match, 2, match, result);
17
+ return result;
18
+ }
19
+
20
+ static VALUE rb_reg_match_last_hook(VALUE match) {
21
+ VALUE result = rb_reg_match_last_original(match);
22
+ result =
23
+ rb_funcall(regexp_class, track_rb_reg_match_last, 2, match, result);
24
+ return result;
25
+ }
26
+
27
+ static VALUE rb_reg_nth_match_hook(int nth, VALUE match) {
28
+ VALUE result = rb_reg_nth_match_original(nth, match);
29
+ result = rb_funcall(regexp_class, track_rb_n_match, 2, match, result);
30
+ return result;
31
+ }
32
+
33
+ static int install_regexp_hooks() {
34
+ funchook_t *funchook = funchook_create();
35
+
36
+ rb_reg_match_pre_original = rb_reg_match_pre;
37
+ funchook_prepare(funchook, (void **)&rb_reg_match_pre_original,
38
+ rb_reg_match_pre_hook);
39
+
40
+ rb_reg_match_post_original = rb_reg_match_post;
41
+ funchook_prepare(funchook, (void **)&rb_reg_match_post_original,
42
+ rb_reg_match_post_hook);
43
+
44
+ rb_reg_match_last_original = rb_reg_match_last;
45
+ funchook_prepare(funchook, (void **)&rb_reg_match_last_original,
46
+ rb_reg_match_last_hook);
47
+
48
+ rb_reg_nth_match_original = rb_reg_nth_match;
49
+ funchook_prepare(funchook, (void **)&rb_reg_nth_match_original,
50
+ rb_reg_nth_match_hook);
51
+
52
+ funchook_install(funchook, 0);
53
+ return 0;
54
+ }
55
+
56
+ void Init_cs__assess_regexp_track(void) {
57
+ regexp_class = rb_define_class("Regexp", rb_cObject);
58
+ track_rb_n_match = rb_intern("track_rb_n_match");
59
+ track_rb_pre_match = rb_intern("track_rb_pre_match");
60
+ track_rb_post_match = rb_intern("track_rb_post_match");
61
+ track_rb_reg_match_last = rb_intern("track_rb_reg_match_last");
62
+ install_regexp_hooks();
63
+ }