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,82 @@
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
+ cs__scoped_require 'contrast/core_extensions/module'
6
+ cs__scoped_require 'contrast/utils/object_share'
7
+
8
+ module Contrast
9
+ module Agent
10
+ module Assess
11
+ # This is used to revert, or undo, the patches that we've placed into
12
+ # modules. This is necessary for those cases where the original method
13
+ # was supposed to be removed, but wasn't b/c we had renamed it -- looking
14
+ # at you, FactoryBot
15
+ class ClassReverter
16
+ include Contrast::Components::Interface
17
+ access_component :logging, :scope
18
+
19
+ class << self
20
+ def unpatch!
21
+ Contrast::Agent::FeatureState.instance.uninstrument_namespaces.
22
+ each { |mod_sym| revert_module mod_sym }
23
+ end
24
+
25
+ private
26
+
27
+ def revert_module mod
28
+ with_contrast_scope do
29
+ revert_child_modules(mod, [])
30
+ end
31
+ rescue StandardError => e
32
+ logger.error(e, "Unable to remove patches from the module #{ mod }")
33
+ end
34
+
35
+ def revert_child_modules mod, reverted_modules, parent_mod = nil
36
+ return if parent_mod == mod
37
+ return if reverted_modules.include?(mod)
38
+
39
+ reverted_modules << mod
40
+
41
+ immediate_constants = mod.cs__constants(false).collect! { |k| mod.cs__const_get(k) }
42
+ immediate_constants.select! { |k| k.is_a?(Module) }
43
+ immediate_constants.flatten!
44
+ if immediate_constants.any?
45
+ immediate_constants.each do |const|
46
+ revert_aliases(const)
47
+ revert_child_modules(const, reverted_modules, mod)
48
+ end
49
+ else
50
+ revert_aliases(mod)
51
+ end
52
+ end
53
+
54
+ # in order to fully uninstrument classes we must use true when getting the singleton/instance methods
55
+ # that way if a class makes use of instance_eval for instance(defined on Kernel) we are able to revert this
56
+ # specific instance of that method to use the default behavior while leaving the remainder of
57
+ # objects using the patched behavior
58
+ def revert_aliases clazz
59
+ marker = Contrast::Utils::ObjectShare::CONTRAST_PATCHED_METHOD_START
60
+ instance_methods = (clazz.instance_methods(true) + clazz.private_instance_methods(true)).select { |method| method.to_s.start_with?(marker) }
61
+ singleton_methods = clazz.cs__singleton_class.instance_methods(true).select { |method| method.to_s.start_with?(marker) }
62
+ instance_methods.each { |i_method| revert_alias(clazz, i_method, instance_methods) }
63
+ singleton_methods.each { |s_method| revert_alias(clazz.cs__singleton_class, s_method, singleton_methods) }
64
+ end
65
+
66
+ def revert_alias clazz, current_method_name, methods
67
+ original_method_name = clazz.instance_method(current_method_name).original_name
68
+
69
+ is_private = clazz.private_method_defined?(original_method_name)
70
+
71
+ # revert aliasing only for those methods currently defined on the original
72
+ if is_private || clazz.method_defined?(original_method_name)
73
+ clazz.send(:alias_method, original_method_name, current_method_name)
74
+ clazz.send(:private, original_method_name) if is_private
75
+ end
76
+ clazz.send(:undef_method, current_method_name) if methods.include?(current_method_name)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,398 @@
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/prevent_serialization'
5
+
6
+ module Contrast
7
+ module Agent
8
+ module Assess
9
+ # This class holds the data about an event in the application
10
+ # We'll use it to build an event that TeamServer can consume if
11
+ # the object to which this event belongs ends in a trigger.
12
+ class ContrastEvent
13
+ include Contrast::Utils::PreventSerialization
14
+
15
+ class << self
16
+ def safe_args_representation args
17
+ return nil unless args
18
+ return Contrast::Utils::ObjectShare::EMPTY_ARRAY if args.empty?
19
+
20
+ rep = []
21
+ args.each do |arg|
22
+ # We have to handle named args
23
+ rep << if arg.is_a?(Hash)
24
+ safe_arg_hash_representation(arg)
25
+ else
26
+ arg.cs__inspect
27
+ end
28
+ end
29
+ rep
30
+ end
31
+
32
+ def safe_arg_hash_representation hash
33
+ # since this is the named hash for arguments, only the value is
34
+ # suspect here
35
+ hash.transform_values(&:cs__inspect)
36
+ end
37
+
38
+ # if given an object that can be duped, duplicate it. otherwise just
39
+ # return the original object. swallow all exceptions from
40
+ # non-duplicable things.
41
+ #
42
+ # we can't just check respond_to? though b/c dup exists on the
43
+ # base Object class
44
+ def safe_dup original
45
+ return nil unless original
46
+
47
+ begin
48
+ original.dup
49
+ rescue StandardError
50
+ original
51
+ end
52
+ end
53
+ end
54
+
55
+ attr_accessor :source_name
56
+ attr_reader :event_id, :source_type, :parent_ids
57
+
58
+ # We need this to track the parent id's of events to build up a flow
59
+ # chart of the finding
60
+ @atomic_id = 0
61
+ @atomic_mutex = Mutex.new
62
+ def self.next_atomic_id
63
+ @atomic_mutex.synchronize do
64
+ begin
65
+ @atomic_id += 1
66
+ # Rollover things
67
+ rescue StandardError
68
+ @atomic_id = 1
69
+ end
70
+ end
71
+ end
72
+
73
+ def initialize policy_node, tagged, object, ret, args, invoked = 0, source_type = nil, source_name = nil
74
+ @caller = caller_locations(get_call_start(policy_node, invoked), 10)
75
+ @policy_node = policy_node
76
+ @time = Contrast::Utils::Timer.now_ms
77
+ @thread = Thread.current.object_id
78
+ @source_type = source_type
79
+ @source_name = source_name
80
+
81
+ # These methods rely on the above being set. Don't move them!
82
+ @event_id = Contrast::Agent::Assess::ContrastEvent.next_atomic_id
83
+ @parent_ids = find_parent_ids(policy_node, object, ret, args)
84
+ snapshot(tagged, object, ret, args)
85
+ end
86
+
87
+ # Parent IDs are the event ids of all the sources of this event which
88
+ # were tracked prior to this event occurring
89
+ def find_parent_ids policy_node, object, ret, args
90
+ return if policy_node.is_a?(Contrast::Agent::Assess::Policy::SourceNode)
91
+
92
+ mapped = policy_node.sources.map do |source|
93
+ value_of_source(source, object, ret, args)
94
+ end
95
+ selected = mapped.select do |source|
96
+ source &&
97
+ Contrast::Utils::DuckUtils.quacks_to?(source, :cs__properties) &&
98
+ source.cs__properties.events &&
99
+ source.cs__properties.events.last
100
+ end
101
+ selected.map do |source|
102
+ source.cs__properties.events.last.event_id
103
+ end
104
+ end
105
+
106
+ def snapshot tagged, object, ret, args
107
+ target = @policy_node.target
108
+ case target
109
+ # If the target is nil, this rule was violated simply by a method
110
+ # being called. We'll save all the information, but nothing will be
111
+ # marked up, as nothing need be tracked
112
+ when nil
113
+ @object = object.cs__inspect
114
+ @args = cs__class.safe_args_representation(args)
115
+ @ret = ret.cs__inspect
116
+ # If the target is O, then we dup the O and safely represent the rest
117
+ when Contrast::Utils::ObjectShare::OBJECT_KEY
118
+ @object = cs__class.safe_dup(tagged)
119
+ @args = cs__class.safe_args_representation(args)
120
+ @ret = ret.cs__inspect
121
+ # If the target is R, then we dup the R and safely represent the rest
122
+ when Contrast::Utils::ObjectShare::RETURN_KEY
123
+ @object = object.cs__inspect
124
+ @args = cs__class.safe_args_representation(args)
125
+ @ret = cs__class.safe_dup(tagged)
126
+ # If the target is P*, then we need to dup things a differently. We
127
+ # need to find the true target inside so that we can mark it up
128
+ # later, but the other args should be represented as their safe form.
129
+ else
130
+ @object = object.cs__inspect
131
+ @args = cs__class.safe_args_representation(args)
132
+ @ret = ret.cs__inspect
133
+ save_target_arg(target, tagged)
134
+ end
135
+ end
136
+
137
+ # I know we're creating an extra string here since we replace the safe
138
+ # one w/ a dup, but good enough for now. Trying not to make this too
139
+ # complicated. - HM 8/8/19
140
+ def save_target_arg target, tagged
141
+ if target.is_a?(Integer)
142
+ @args[target] = cs__class.safe_dup(tagged)
143
+ return
144
+ end
145
+
146
+ @args.each_with_index do |search, index|
147
+ next unless search.is_a?(Hash)
148
+ next unless search[target]
149
+
150
+ search[target] = cs__class.safe_dup(tagged)
151
+ @highlight = index
152
+ break
153
+ end
154
+ end
155
+
156
+ def value_of_source source, object, ret, args
157
+ case source
158
+ when Contrast::Utils::ObjectShare::OBJECT_KEY
159
+ object
160
+ when Contrast::Utils::ObjectShare::RETURN_KEY
161
+ ret
162
+ else
163
+ if source.is_a?(Integer)
164
+ args[source]
165
+ else
166
+ args.each do |search|
167
+ next unless search.is_a?(Hash)
168
+
169
+ s = search[source]
170
+ return s if s
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ # each policy_node has a certain number of levels down it calls
177
+ # before getting here. since we know them, we can skip
178
+ # right to the part of the stack we care about.
179
+ #
180
+ # Note: if our callstack changes, this number has to change
181
+ def get_call_start policy_node, invoked
182
+ # TODO: RUBY-440 audit these numbers to get stacktraces to render
183
+ # properly
184
+ base = case policy_node
185
+ when Contrast::Agent::Assess::Policy::SourceNode
186
+ 6
187
+ when Contrast::Agent::Assess::Policy::PropagationNode
188
+ 7
189
+ when Contrast::Agent::Assess::Policy::TriggerNode
190
+ 7
191
+ else
192
+ 2
193
+ end
194
+ base + invoked
195
+ end
196
+
197
+ # Convert this event into a DTM that TeamServer can consume
198
+ def to_dtm_event
199
+ event = Contrast::Api::Dtm::TraceEvent.new
200
+
201
+ # Figure out what the target of this event was. It's a little
202
+ # annoying for us since P can be named (thanks, Ruby) where
203
+ # as for everyone else it is idx based.
204
+ taint_target = determine_taint_target(event)
205
+
206
+ event.type = @policy_node.node_type
207
+ event.action = @policy_node.build_action
208
+ event.timestamp_ms = @time.to_i
209
+ event.thread = Contrast::Utils::StringUtils.force_utf8(@thread)
210
+ truncate_obj = Contrast::Utils::ObjectShare::OBJECT_KEY != taint_target
211
+ event.object = build_event_object(@object, truncate_obj)
212
+ truncate_ret = Contrast::Utils::ObjectShare::RETURN_KEY != taint_target
213
+ event.ret = build_event_object(@ret, truncate_ret)
214
+ built_args = build_event_args(taint_target)
215
+ built_args.each do |arg|
216
+ event.args << arg
217
+ end
218
+ taint_ranges = find_taint_ranges(@object, @args, @ret, taint_target)
219
+ taint_ranges.each do |range|
220
+ event.taint_ranges << range
221
+ end
222
+
223
+ # We delayed doing this as long as possible b/c it's expensive
224
+ stack = Contrast::Utils::StackTraceUtils.to_dtm_stack(
225
+ stack_locations: @caller,
226
+ rasp_element: false)
227
+ stack.each do |frame|
228
+ event.stack << frame
229
+ end
230
+
231
+ event.field_name = Contrast::Utils::StringUtils.force_utf8(source_name)
232
+
233
+ event_source_dtm = build_event_source_dtm
234
+ event.event_sources << event_source_dtm if event_source_dtm
235
+
236
+ event.object_id = event_id.to_i
237
+ @parent_ids&.each do |id|
238
+ parent = Contrast::Api::Dtm::ParentObjectId.new
239
+ parent.id = id.to_i
240
+ event.parent_object_ids << parent
241
+ end
242
+
243
+ # not to be confused w/ the partial signature
244
+ build_complete_signature(event)
245
+
246
+ event
247
+ end
248
+
249
+ def forced_source_type
250
+ @_forced_source_type ||= Contrast::Utils::StringUtils.force_utf8(source_type)
251
+ end
252
+
253
+ def forced_source_name
254
+ @_forced_source_name ||= Contrast::Utils::StringUtils.force_utf8(source_name)
255
+ end
256
+
257
+ # Probably only for source events, but we'll go
258
+ # with source_type instead. java & .net support source_type
259
+ # in propagation events, so we'll future proof this
260
+ def build_event_source_dtm
261
+ # You can have a source w/o a name, but not w/o a type
262
+ return unless source_type
263
+
264
+ dtm = Contrast::Api::Dtm::TraceEventSource.new
265
+ dtm.type = forced_source_type
266
+ dtm.name = forced_source_name
267
+ dtm
268
+ end
269
+
270
+ # We're not going to build the signature string here, b/c we have all
271
+ # the composite pieces of it. Instead, we're going to let TeamServer
272
+ # render this for us.
273
+ def build_complete_signature event
274
+ signature = Contrast::Api::Dtm::TraceEventSignature.new
275
+ event.signature = signature
276
+ return_type = @ret ? @ret.cs__class.name : Contrast::Utils::ObjectShare::NIL_STRING
277
+ signature.return_type = Contrast::Utils::StringUtils.force_utf8(return_type)
278
+ signature.class_name = Contrast::Utils::StringUtils.force_utf8(@policy_node.class_name)
279
+ signature.method_name = Contrast::Utils::StringUtils.force_utf8(@policy_node.method_name)
280
+ if @args
281
+ @args&.each do |arg|
282
+ arg_type = arg ? arg.cs__class.name : Contrast::Utils::ObjectShare::NIL_STRING
283
+ signature.arg_types << Contrast::Utils::StringUtils.force_utf8(arg_type)
284
+ end
285
+ end
286
+ signature.constructor = @policy_node.method_name == :new
287
+ # if there's a ret, then this method isn't nil. not 100% full proof since you can
288
+ # return nil, but this is the best we've got currently.
289
+ signature.void_method = @ret.nil?
290
+ # 8 is STATIC in Java... we have to placate them for now
291
+ # it has been requested that flags be removed since it isn't used
292
+ signature.flags = 8 unless @policy_node.instance_method?
293
+ end
294
+
295
+ # Wrapper around build_event_object for the args array. Handles
296
+ # tainting the correct argument.
297
+ def build_event_args taint_target
298
+ event_args = []
299
+ @args.each_index do |idx|
300
+ truncate_arg = taint_target != idx
301
+ event_arg = build_event_object(@args[idx], truncate_arg)
302
+ event_args << event_arg
303
+ end
304
+ event_args
305
+ end
306
+
307
+ # Build the event object. We were originally going to include taint on
308
+ # each one, but TS doesn't accept / use that, so it is a waste of time.
309
+ #
310
+ # We'll truncate any object that isn't important to the taint ranges of
311
+ # this event, so that we don't murder TeamServer by, for instance,
312
+ # hypothetically sending the entire rendered HTML page >_> <_< >_>
313
+ ELLIPSIS = '...'
314
+ UNTRUNCATED_PORTION_LENGTH = 25
315
+ TRUNCATION_LENGTH = (UNTRUNCATED_PORTION_LENGTH * 2) + 3 # ELLIPSIS length
316
+ def build_event_object object, truncate
317
+ event_object = Contrast::Api::Dtm::TraceEventObject.new
318
+ obj_string = Contrast::Utils::StringUtils.force_utf8(object)
319
+ if truncate && Contrast::Utils::StringUtils.ret_length(obj_string) > TRUNCATION_LENGTH
320
+ tmp = []
321
+ tmp << obj_string[0, UNTRUNCATED_PORTION_LENGTH]
322
+ tmp << ELLIPSIS
323
+ tmp << obj_string[
324
+ obj_string.length - UNTRUNCATED_PORTION_LENGTH,
325
+ UNTRUNCATED_PORTION_LENGTH]
326
+ obj_string = tmp.join
327
+ end
328
+ event_object.value = Base64.encode64(obj_string)
329
+ event_object.tracked = Contrast::Utils::Assess::TrackingUtil.tracked?(object)
330
+ event_object
331
+ end
332
+
333
+ # We have to do a little work to figure out what our TS appropriate
334
+ # target is. To break this down, the logic is as follows:
335
+ # 1) If my policy_node has a target, work on targets. Else, work on sources.
336
+ # Per TS law, each policy_node must have at least a source or a target.
337
+ # The only type of policy_node w/o targets is a Trigger, but that may
338
+ # change.
339
+ # 2) If I have a highlight, it means that I have a P target that is
340
+ # not in integer form (it was a named / keyword type for which I had
341
+ # to find the index). I need to address this so that TS can process
342
+ # it.
343
+ # 3) I'll set the event's source and target to TS values.
344
+ # 4) Return the highlight or the first source/target as the taint
345
+ # target.
346
+ def determine_taint_target event
347
+ if @policy_node&.targets&.any?
348
+ event.source = @policy_node.source_string if @policy_node.source_string
349
+ event.target = if @highlight
350
+ "P#{ @highlight }"
351
+ else
352
+ @policy_node.target_string
353
+ end
354
+ @highlight || @policy_node.targets[0]
355
+ elsif @policy_node&.sources&.any?
356
+ event.source = if @highlight
357
+ "P#{ @highlight }"
358
+ else
359
+ @policy_node.source_string
360
+ end
361
+ event.target = @policy_node.target_string if @policy_node.target_string
362
+ @highlight || @policy_node.sources[0]
363
+ end
364
+ end
365
+
366
+ # TeamServer only supports one object's taint ranges at a time.
367
+ # We'll find the taint ranges for the target and return those
368
+ def find_taint_ranges object, args, ret, taint_target
369
+ # If there's no taint_target, this isn't a dataflow trace, but a
370
+ # trigger one
371
+ return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless taint_target
372
+
373
+ properties = case taint_target
374
+ when Contrast::Utils::ObjectShare::OBJECT_KEY
375
+ object.cs__properties
376
+ when Contrast::Utils::ObjectShare::RETURN_KEY
377
+ ret.cs__properties
378
+ else
379
+ target = args[taint_target]
380
+ if target.is_a?(Hash)
381
+ if @policy_node&.targets&.any?
382
+ target[@policy_node.targets[0]].cs__properties
383
+ else
384
+ target[@policy_node.sources[0]].cs__properties
385
+ end
386
+ else
387
+ target.cs__properties
388
+ end
389
+ end
390
+
391
+ return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless properties.tracked?
392
+
393
+ properties.tags_to_dtm
394
+ end
395
+ end
396
+ end
397
+ end
398
+ end