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.
- checksums.yaml +7 -0
- data/.clang-format +5 -0
- data/.dockerignore +10 -0
- data/.gitignore +58 -0
- data/.gitmodules +6 -0
- data/.rspec +6 -0
- data/.simplecov +4 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +12 -0
- data/Rakefile +15 -0
- data/exe/contrast_service +29 -0
- data/ext/build_funchook.rb +48 -0
- data/ext/cs__assess_active_record_named/cs__active_record_named.c +47 -0
- data/ext/cs__assess_active_record_named/cs__active_record_named.h +10 -0
- data/ext/cs__assess_active_record_named/extconf.rb +2 -0
- data/ext/cs__assess_array/cs__assess_array.c +38 -0
- data/ext/cs__assess_array/cs__assess_array.h +9 -0
- data/ext/cs__assess_array/extconf.rb +2 -0
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +50 -0
- data/ext/cs__assess_basic_object/cs__assess_basic_object.h +17 -0
- data/ext/cs__assess_basic_object/extconf.rb +2 -0
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +86 -0
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +34 -0
- data/ext/cs__assess_fiber_track/extconf.rb +2 -0
- data/ext/cs__assess_hash/cs__assess_hash.c +64 -0
- data/ext/cs__assess_hash/cs__assess_hash.h +24 -0
- data/ext/cs__assess_hash/extconf.rb +2 -0
- data/ext/cs__assess_kernel/cs__assess_kernel.c +36 -0
- data/ext/cs__assess_kernel/cs__assess_kernel.h +10 -0
- data/ext/cs__assess_kernel/extconf.rb +2 -0
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +47 -0
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +18 -0
- data/ext/cs__assess_marshal_module/extconf.rb +2 -0
- data/ext/cs__assess_module/cs__assess_module.c +78 -0
- data/ext/cs__assess_module/cs__assess_module.h +25 -0
- data/ext/cs__assess_module/extconf.rb +2 -0
- data/ext/cs__assess_regexp/cs__assess_regexp.c +48 -0
- data/ext/cs__assess_regexp/cs__assess_regexp.h +22 -0
- data/ext/cs__assess_regexp/extconf.rb +2 -0
- data/ext/cs__assess_regexp_track/cs__assess_regexp_track.c +63 -0
- data/ext/cs__assess_regexp_track/cs__assess_regexp_track.h +29 -0
- data/ext/cs__assess_regexp_track/extconf.rb +2 -0
- data/ext/cs__assess_string/cs__assess_string.c +38 -0
- data/ext/cs__assess_string/cs__assess_string.h +19 -0
- data/ext/cs__assess_string/extconf.rb +2 -0
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +31 -0
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.h +13 -0
- data/ext/cs__assess_string_interpolation26/extconf.rb +2 -0
- data/ext/cs__common/cs__common.c +60 -0
- data/ext/cs__common/cs__common.h +28 -0
- data/ext/cs__common/extconf.rb +20 -0
- data/ext/cs__contrast_patch/cs__contrast_patch.c +445 -0
- data/ext/cs__contrast_patch/cs__contrast_patch.h +196 -0
- data/ext/cs__contrast_patch/extconf.rb +2 -0
- data/ext/cs__protect_kernel/cs__protect_kernel.c +37 -0
- data/ext/cs__protect_kernel/cs__protect_kernel.h +11 -0
- data/ext/cs__protect_kernel/extconf.rb +2 -0
- data/ext/cs__scope/cs__scope.c +96 -0
- data/ext/cs__scope/cs__scope.h +33 -0
- data/ext/cs__scope/extconf.rb +2 -0
- data/ext/extconf_common.rb +49 -0
- data/funchook/LICENSE +360 -0
- data/funchook/Makefile +29 -0
- data/funchook/Makefile.in +29 -0
- data/funchook/README.md +121 -0
- data/funchook/appveyor.yml +42 -0
- data/funchook/autogen.sh +3 -0
- data/funchook/autom4te.cache/output.0 +4976 -0
- data/funchook/autom4te.cache/requests +78 -0
- data/funchook/autom4te.cache/traces.0 +364 -0
- data/funchook/config.guess +1530 -0
- data/funchook/config.log +490 -0
- data/funchook/config.status +1016 -0
- data/funchook/config.sub +1773 -0
- data/funchook/configure +4976 -0
- data/funchook/configure.ac +59 -0
- data/funchook/distorm/COPYING +26 -0
- data/funchook/distorm/MANIFEST +25 -0
- data/funchook/distorm/MANIFEST.in +4 -0
- data/funchook/distorm/README.md +12 -0
- data/funchook/distorm/disOps/disOps.py +795 -0
- data/funchook/distorm/disOps/x86db.py +404 -0
- data/funchook/distorm/disOps/x86header.py +247 -0
- data/funchook/distorm/disOps/x86sets.py +1664 -0
- data/funchook/distorm/examples/cs/TestdiStorm/Program.cs +79 -0
- data/funchook/distorm/examples/cs/TestdiStorm/Properties/AssemblyInfo.cs +36 -0
- data/funchook/distorm/examples/cs/TestdiStorm/TestdiStorm.csproj +69 -0
- data/funchook/distorm/examples/cs/distorm-net.sln +26 -0
- data/funchook/distorm/examples/cs/distorm-net/CodeInfo.cs +23 -0
- data/funchook/distorm/examples/cs/distorm-net/DecodedInst.cs +15 -0
- data/funchook/distorm/examples/cs/distorm-net/DecodedResult.cs +14 -0
- data/funchook/distorm/examples/cs/distorm-net/DecomposedInst.cs +36 -0
- data/funchook/distorm/examples/cs/distorm-net/DecomposedResult.cs +14 -0
- data/funchook/distorm/examples/cs/distorm-net/Opcodes.cs +1268 -0
- data/funchook/distorm/examples/cs/distorm-net/Opcodes.tt +37 -0
- data/funchook/distorm/examples/cs/distorm-net/Operand.cs +25 -0
- data/funchook/distorm/examples/cs/distorm-net/Properties/AssemblyInfo.cs +36 -0
- data/funchook/distorm/examples/cs/distorm-net/diStorm3.cs +411 -0
- data/funchook/distorm/examples/cs/distorm-net/distorm-net.csproj +80 -0
- data/funchook/distorm/examples/cs/readme +3 -0
- data/funchook/distorm/examples/ddk/README +48 -0
- data/funchook/distorm/examples/ddk/distorm.ini +11 -0
- data/funchook/distorm/examples/ddk/dummy.c +15 -0
- data/funchook/distorm/examples/ddk/main.c +91 -0
- data/funchook/distorm/examples/ddk/makefile +1 -0
- data/funchook/distorm/examples/ddk/sources +10 -0
- data/funchook/distorm/examples/java/Makefile +23 -0
- data/funchook/distorm/examples/java/distorm/src/Main.java +43 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/CodeInfo.java +27 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedInst.java +32 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedResult.java +11 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedInst.java +89 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedResult.java +11 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/OpcodeEnum.java +131 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/Opcodes.java +1123 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/Operand.java +24 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/distorm3.java +41 -0
- data/funchook/distorm/examples/java/jdistorm.c +405 -0
- data/funchook/distorm/examples/java/jdistorm.h +40 -0
- data/funchook/distorm/examples/java/jdistorm.sln +20 -0
- data/funchook/distorm/examples/java/jdistorm.vcproj +208 -0
- data/funchook/distorm/examples/linux/Makefile +15 -0
- data/funchook/distorm/examples/linux/main.c +181 -0
- data/funchook/distorm/examples/tests/Makefile +15 -0
- data/funchook/distorm/examples/tests/main.cpp +42 -0
- data/funchook/distorm/examples/tests/main.py +66 -0
- data/funchook/distorm/examples/tests/test_distorm3.py +1672 -0
- data/funchook/distorm/examples/tests/tests.sln +20 -0
- data/funchook/distorm/examples/tests/tests.vcxproj +82 -0
- data/funchook/distorm/examples/tests/tests.vcxproj.filters +22 -0
- data/funchook/distorm/examples/win32/disasm.sln +25 -0
- data/funchook/distorm/examples/win32/disasm.vcxproj +201 -0
- data/funchook/distorm/examples/win32/disasm.vcxproj.filters +14 -0
- data/funchook/distorm/examples/win32/main.cpp +163 -0
- data/funchook/distorm/include/distorm.h +482 -0
- data/funchook/distorm/include/mnemonics.h +301 -0
- data/funchook/distorm/make/linux/Makefile +28 -0
- data/funchook/distorm/make/mac/Makefile +24 -0
- data/funchook/distorm/make/win32/cdistorm.vcxproj +239 -0
- data/funchook/distorm/make/win32/cdistorm.vcxproj.filters +80 -0
- data/funchook/distorm/make/win32/distorm.sln +25 -0
- data/funchook/distorm/make/win32/resource.h +14 -0
- data/funchook/distorm/make/win32/resource.rc +99 -0
- data/funchook/distorm/python/distorm3/__init__.py +957 -0
- data/funchook/distorm/python/distorm3/sample.py +51 -0
- data/funchook/distorm/setup.cfg +10 -0
- data/funchook/distorm/setup.py +266 -0
- data/funchook/distorm/src/config.h +169 -0
- data/funchook/distorm/src/decoder.c +641 -0
- data/funchook/distorm/src/decoder.h +33 -0
- data/funchook/distorm/src/distorm.c +413 -0
- data/funchook/distorm/src/instructions.c +597 -0
- data/funchook/distorm/src/instructions.h +463 -0
- data/funchook/distorm/src/insts.c +7939 -0
- data/funchook/distorm/src/insts.h +64 -0
- data/funchook/distorm/src/mnemonics.c +284 -0
- data/funchook/distorm/src/operands.c +1290 -0
- data/funchook/distorm/src/operands.h +28 -0
- data/funchook/distorm/src/prefix.c +368 -0
- data/funchook/distorm/src/prefix.h +64 -0
- data/funchook/distorm/src/textdefs.c +172 -0
- data/funchook/distorm/src/textdefs.h +57 -0
- data/funchook/distorm/src/wstring.c +47 -0
- data/funchook/distorm/src/wstring.h +35 -0
- data/funchook/distorm/src/x86defs.h +82 -0
- data/funchook/include/funchook.h +123 -0
- data/funchook/install-sh +527 -0
- data/funchook/src/Makefile +70 -0
- data/funchook/src/Makefile.in +70 -0
- data/funchook/src/__strerror.h +109 -0
- data/funchook/src/config.h +101 -0
- data/funchook/src/config.h.in +100 -0
- data/funchook/src/decoder.o +0 -0
- data/funchook/src/distorm.o +0 -0
- data/funchook/src/funchook.c +440 -0
- data/funchook/src/funchook.o +0 -0
- data/funchook/src/funchook_internal.h +155 -0
- data/funchook/src/funchook_io.c +182 -0
- data/funchook/src/funchook_io.h +64 -0
- data/funchook/src/funchook_io.o +0 -0
- data/funchook/src/funchook_syscall.S +134 -0
- data/funchook/src/funchook_syscall.o +0 -0
- data/funchook/src/funchook_unix.c +480 -0
- data/funchook/src/funchook_unix.o +0 -0
- data/funchook/src/funchook_windows.c +397 -0
- data/funchook/src/funchook_x86.c +622 -0
- data/funchook/src/funchook_x86.o +0 -0
- data/funchook/src/instructions.o +0 -0
- data/funchook/src/insts.o +0 -0
- data/funchook/src/libfunchook.so +0 -0
- data/funchook/src/mnemonics.o +0 -0
- data/funchook/src/operands.o +0 -0
- data/funchook/src/os_func.c +115 -0
- data/funchook/src/os_func.h +75 -0
- data/funchook/src/os_func.o +0 -0
- data/funchook/src/os_func_unix.c +94 -0
- data/funchook/src/os_func_unix.o +0 -0
- data/funchook/src/os_func_windows.c +32 -0
- data/funchook/src/prefix.o +0 -0
- data/funchook/src/printf_base.c +1688 -0
- data/funchook/src/printf_base.h +46 -0
- data/funchook/src/printf_base.o +0 -0
- data/funchook/src/textdefs.o +0 -0
- data/funchook/src/wstring.o +0 -0
- data/funchook/test/Makefile +43 -0
- data/funchook/test/Makefile.in +43 -0
- data/funchook/test/funchook_test +0 -0
- data/funchook/test/libfunchook_test.c +25 -0
- data/funchook/test/libfunchook_test.so +0 -0
- data/funchook/test/libfunchook_test2.c +18 -0
- data/funchook/test/suffix.list +600 -0
- data/funchook/test/test_main.c +430 -0
- data/funchook/test/test_main.o +0 -0
- data/funchook/test/x86_64_test.S +10 -0
- data/funchook/test/x86_64_test.o +0 -0
- data/funchook/test/x86_test.S +339 -0
- data/funchook/win32/config.h +1 -0
- data/funchook/win32/funchook.sln +52 -0
- data/funchook/win32/funchook.vcxproj +188 -0
- data/funchook/win32/funchook.vcxproj.filters +84 -0
- data/funchook/win32/funchook_test.vcxproj +170 -0
- data/funchook/win32/funchook_test.vcxproj.filters +22 -0
- data/funchook/win32/funchook_test_dll.vcxproj +184 -0
- data/funchook/win32/funchook_test_dll.vcxproj.filters +30 -0
- data/funchook/win32/funchook_test_exe.def +3 -0
- data/lib/contrast-agent.rb +8 -0
- data/lib/contrast.rb +57 -0
- data/lib/contrast/agent.rb +80 -0
- data/lib/contrast/agent/assess.rb +45 -0
- data/lib/contrast/agent/assess/adjusted_span.rb +25 -0
- data/lib/contrast/agent/assess/class_reverter.rb +82 -0
- data/lib/contrast/agent/assess/contrast_event.rb +398 -0
- data/lib/contrast/agent/assess/frozen_properties.rb +41 -0
- data/lib/contrast/agent/assess/insulator.rb +53 -0
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +78 -0
- data/lib/contrast/agent/assess/policy/patcher.rb +85 -0
- data/lib/contrast/agent/assess/policy/policy.rb +116 -0
- data/lib/contrast/agent/assess/policy/policy_node.rb +289 -0
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +44 -0
- data/lib/contrast/agent/assess/policy/preshift.rb +94 -0
- data/lib/contrast/agent/assess/policy/propagation_method.rb +260 -0
- data/lib/contrast/agent/assess/policy/propagation_node.rb +127 -0
- data/lib/contrast/agent/assess/policy/propagator.rb +35 -0
- data/lib/contrast/agent/assess/policy/propagator/append.rb +54 -0
- data/lib/contrast/agent/assess/policy/propagator/base.rb +37 -0
- data/lib/contrast/agent/assess/policy/propagator/center.rb +73 -0
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +36 -0
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +62 -0
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +55 -0
- data/lib/contrast/agent/assess/policy/propagator/keep.rb +26 -0
- data/lib/contrast/agent/assess/policy/propagator/next.rb +42 -0
- data/lib/contrast/agent/assess/policy/propagator/prepend.rb +50 -0
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +76 -0
- data/lib/contrast/agent/assess/policy/propagator/replace.rb +27 -0
- data/lib/contrast/agent/assess/policy/propagator/reverse.rb +38 -0
- data/lib/contrast/agent/assess/policy/propagator/select.rb +86 -0
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +60 -0
- data/lib/contrast/agent/assess/policy/propagator/split.rb +49 -0
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +169 -0
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +81 -0
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +79 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +209 -0
- data/lib/contrast/agent/assess/policy/source_node.rb +62 -0
- data/lib/contrast/agent/assess/policy/trigger_method.rb +209 -0
- data/lib/contrast/agent/assess/policy/trigger_node.rb +198 -0
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +77 -0
- data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +31 -0
- data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +40 -0
- data/lib/contrast/agent/assess/properties.rb +392 -0
- data/lib/contrast/agent/assess/rule.rb +18 -0
- data/lib/contrast/agent/assess/rule/base.rb +72 -0
- data/lib/contrast/agent/assess/rule/csrf.rb +66 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_action.rb +28 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +69 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_watcher.rb +132 -0
- data/lib/contrast/agent/assess/rule/provider.rb +21 -0
- data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +62 -0
- data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +73 -0
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +121 -0
- data/lib/contrast/agent/assess/rule/redos.rb +68 -0
- data/lib/contrast/agent/assess/rule/response_scanning_rule.rb +47 -0
- data/lib/contrast/agent/assess/rule/response_watcher.rb +36 -0
- data/lib/contrast/agent/assess/rule/watcher.rb +36 -0
- data/lib/contrast/agent/assess/tag.rb +151 -0
- data/lib/contrast/agent/at_exit_hook.rb +33 -0
- data/lib/contrast/agent/class_reopener.rb +195 -0
- data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +26 -0
- data/lib/contrast/agent/deadzone/policy/policy.rb +57 -0
- data/lib/contrast/agent/disable_reaction.rb +24 -0
- data/lib/contrast/agent/exclusion_matcher.rb +190 -0
- data/lib/contrast/agent/feature_state.rb +379 -0
- data/lib/contrast/agent/inventory/policy/policy.rb +32 -0
- data/lib/contrast/agent/inventory/policy/trigger_node.rb +22 -0
- data/lib/contrast/agent/logger_manager.rb +116 -0
- data/lib/contrast/agent/middleware.rb +352 -0
- data/lib/contrast/agent/module_data.rb +16 -0
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +37 -0
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +58 -0
- data/lib/contrast/agent/patching/policy/method_policy.rb +94 -0
- data/lib/contrast/agent/patching/policy/module_policy.rb +116 -0
- data/lib/contrast/agent/patching/policy/patch.rb +312 -0
- data/lib/contrast/agent/patching/policy/patch_status.rb +192 -0
- data/lib/contrast/agent/patching/policy/patcher.rb +310 -0
- data/lib/contrast/agent/patching/policy/policy.rb +138 -0
- data/lib/contrast/agent/patching/policy/policy_node.rb +80 -0
- data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +28 -0
- data/lib/contrast/agent/patching/policy/trigger_node.rb +81 -0
- data/lib/contrast/agent/protect/policy/policy.rb +37 -0
- data/lib/contrast/agent/protect/policy/trigger_node.rb +23 -0
- data/lib/contrast/agent/protect/rule.rb +58 -0
- data/lib/contrast/agent/protect/rule/base.rb +300 -0
- data/lib/contrast/agent/protect/rule/base_service.rb +88 -0
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +156 -0
- data/lib/contrast/agent/protect/rule/csrf.rb +118 -0
- data/lib/contrast/agent/protect/rule/csrf/csrf_evaluator.rb +103 -0
- data/lib/contrast/agent/protect/rule/csrf/csrf_token_injector.rb +85 -0
- data/lib/contrast/agent/protect/rule/default_scanner.rb +300 -0
- data/lib/contrast/agent/protect/rule/deserialization.rb +193 -0
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +80 -0
- data/lib/contrast/agent/protect/rule/no_sqli.rb +101 -0
- data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +40 -0
- data/lib/contrast/agent/protect/rule/path_traversal.rb +143 -0
- data/lib/contrast/agent/protect/rule/sqli.rb +101 -0
- data/lib/contrast/agent/protect/rule/sqli/default_sql_scanner.rb +16 -0
- data/lib/contrast/agent/protect/rule/sqli/mysql_sql_scanner.rb +38 -0
- data/lib/contrast/agent/protect/rule/sqli/postgres_sql_scanner.rb +22 -0
- data/lib/contrast/agent/protect/rule/sqli/sqlite_sql_scanner.rb +19 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +20 -0
- data/lib/contrast/agent/protect/rule/xss.rb +24 -0
- data/lib/contrast/agent/protect/rule/xxe.rb +120 -0
- data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +82 -0
- data/lib/contrast/agent/railtie.rb +30 -0
- data/lib/contrast/agent/reaction_processor.rb +47 -0
- data/lib/contrast/agent/request.rb +493 -0
- data/lib/contrast/agent/request_context.rb +225 -0
- data/lib/contrast/agent/require_state.rb +61 -0
- data/lib/contrast/agent/response.rb +215 -0
- data/lib/contrast/agent/rewriter.rb +244 -0
- data/lib/contrast/agent/scope.rb +28 -0
- data/lib/contrast/agent/service_heartbeat.rb +37 -0
- data/lib/contrast/agent/settings_state.rb +148 -0
- data/lib/contrast/agent/socket_client.rb +125 -0
- data/lib/contrast/agent/thread.rb +26 -0
- data/lib/contrast/agent/tracepoint_hook.rb +51 -0
- data/lib/contrast/agent/version.rb +8 -0
- data/lib/contrast/api.rb +17 -0
- data/lib/contrast/api/.gitkeep +0 -0
- data/lib/contrast/api/connection_status.rb +49 -0
- data/lib/contrast/api/socket.rb +43 -0
- data/lib/contrast/api/speedracer.rb +206 -0
- data/lib/contrast/api/tcp_socket.rb +31 -0
- data/lib/contrast/api/unix_socket.rb +25 -0
- data/lib/contrast/common_agent_configuration.rb +86 -0
- data/lib/contrast/components/agent.rb +85 -0
- data/lib/contrast/components/app_context.rb +188 -0
- data/lib/contrast/components/assess.rb +67 -0
- data/lib/contrast/components/config.rb +135 -0
- data/lib/contrast/components/contrast_service.rb +113 -0
- data/lib/contrast/components/heap_dump.rb +34 -0
- data/lib/contrast/components/interface.rb +178 -0
- data/lib/contrast/components/inventory.rb +23 -0
- data/lib/contrast/components/logger.rb +92 -0
- data/lib/contrast/components/protect.rb +38 -0
- data/lib/contrast/components/sampling.rb +41 -0
- data/lib/contrast/components/scope.rb +106 -0
- data/lib/contrast/components/settings.rb +140 -0
- data/lib/contrast/config.rb +33 -0
- data/lib/contrast/config/agent_configuration.rb +24 -0
- data/lib/contrast/config/application_configuration.rb +27 -0
- data/lib/contrast/config/assess_configuration.rb +22 -0
- data/lib/contrast/config/assess_rules_configuration.rb +18 -0
- data/lib/contrast/config/base_configuration.rb +105 -0
- data/lib/contrast/config/default_value.rb +16 -0
- data/lib/contrast/config/exception_configuration.rb +21 -0
- data/lib/contrast/config/heap_dump_configuration.rb +23 -0
- data/lib/contrast/config/inventory_configuration.rb +20 -0
- data/lib/contrast/config/logger_configuration.rb +20 -0
- data/lib/contrast/config/protect_configuration.rb +20 -0
- data/lib/contrast/config/protect_rule_configuration.rb +37 -0
- data/lib/contrast/config/protect_rules_configuration.rb +30 -0
- data/lib/contrast/config/root_configuration.rb +26 -0
- data/lib/contrast/config/ruby_configuration.rb +39 -0
- data/lib/contrast/config/sampling_configuration.rb +22 -0
- data/lib/contrast/config/server_configuration.rb +23 -0
- data/lib/contrast/config/service_configuration.rb +22 -0
- data/lib/contrast/configuration.rb +214 -0
- data/lib/contrast/core_extensions/assess.rb +51 -0
- data/lib/contrast/core_extensions/assess/array.rb +58 -0
- data/lib/contrast/core_extensions/assess/assess_extension.rb +145 -0
- data/lib/contrast/core_extensions/assess/basic_object.rb +15 -0
- data/lib/contrast/core_extensions/assess/erb.rb +42 -0
- data/lib/contrast/core_extensions/assess/exec_trigger.rb +48 -0
- data/lib/contrast/core_extensions/assess/fiber.rb +125 -0
- data/lib/contrast/core_extensions/assess/hash.rb +22 -0
- data/lib/contrast/core_extensions/assess/kernel.rb +95 -0
- data/lib/contrast/core_extensions/assess/module.rb +14 -0
- data/lib/contrast/core_extensions/assess/regexp.rb +206 -0
- data/lib/contrast/core_extensions/assess/string.rb +75 -0
- data/lib/contrast/core_extensions/assess/tilt_template_trigger.rb +73 -0
- data/lib/contrast/core_extensions/delegator.rb +14 -0
- data/lib/contrast/core_extensions/eval_trigger.rb +52 -0
- data/lib/contrast/core_extensions/inventory.rb +22 -0
- data/lib/contrast/core_extensions/inventory/datastores.rb +37 -0
- data/lib/contrast/core_extensions/module.rb +42 -0
- data/lib/contrast/core_extensions/object.rb +27 -0
- data/lib/contrast/core_extensions/protect.rb +20 -0
- data/lib/contrast/core_extensions/protect/applies_command_injection_rule.rb +70 -0
- data/lib/contrast/core_extensions/protect/applies_deserialization_rule.rb +58 -0
- data/lib/contrast/core_extensions/protect/applies_no_sqli_rule.rb +81 -0
- data/lib/contrast/core_extensions/protect/applies_path_traversal_rule.rb +119 -0
- data/lib/contrast/core_extensions/protect/applies_sqli_rule.rb +63 -0
- data/lib/contrast/core_extensions/protect/applies_xxe_rule.rb +141 -0
- data/lib/contrast/core_extensions/protect/kernel.rb +30 -0
- data/lib/contrast/core_extensions/protect/psych.rb +7 -0
- data/lib/contrast/core_extensions/thread.rb +31 -0
- data/lib/contrast/internal_exception.rb +8 -0
- data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +48 -0
- data/lib/contrast/rails_extensions/assess/active_record.rb +32 -0
- data/lib/contrast/rails_extensions/assess/active_record_named.rb +61 -0
- data/lib/contrast/rails_extensions/assess/configuration.rb +26 -0
- data/lib/contrast/rails_extensions/buffer.rb +30 -0
- data/lib/contrast/rails_extensions/rack.rb +45 -0
- data/lib/contrast/security_exception.rb +14 -0
- data/lib/contrast/sinatra_extensions/assess/cookie.rb +26 -0
- data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +59 -0
- data/lib/contrast/tasks/service.rb +95 -0
- data/lib/contrast/utils/assess/sampling_util.rb +96 -0
- data/lib/contrast/utils/assess/tracking_util.rb +39 -0
- data/lib/contrast/utils/boolean_util.rb +33 -0
- data/lib/contrast/utils/cache.rb +69 -0
- data/lib/contrast/utils/class_util.rb +58 -0
- data/lib/contrast/utils/comment_range.rb +19 -0
- data/lib/contrast/utils/data_store_util.rb +23 -0
- data/lib/contrast/utils/duck_utils.rb +58 -0
- data/lib/contrast/utils/env_configuration_item.rb +52 -0
- data/lib/contrast/utils/environment_util.rb +152 -0
- data/lib/contrast/utils/freeze_util.rb +36 -0
- data/lib/contrast/utils/gemfile_reader.rb +191 -0
- data/lib/contrast/utils/hash_digest.rb +148 -0
- data/lib/contrast/utils/heap_dump_util.rb +113 -0
- data/lib/contrast/utils/invalid_configuration_util.rb +88 -0
- data/lib/contrast/utils/inventory_util.rb +126 -0
- data/lib/contrast/utils/io_util.rb +61 -0
- data/lib/contrast/utils/object_share.rb +117 -0
- data/lib/contrast/utils/operating_environment.rb +38 -0
- data/lib/contrast/utils/os.rb +49 -0
- data/lib/contrast/utils/path_util.rb +151 -0
- data/lib/contrast/utils/performs_logging.rb +152 -0
- data/lib/contrast/utils/preflight_util.rb +13 -0
- data/lib/contrast/utils/prevent_serialization.rb +52 -0
- data/lib/contrast/utils/rack_assess_session_cookie.rb +104 -0
- data/lib/contrast/utils/rails_assess_configuration.rb +95 -0
- data/lib/contrast/utils/random_util.rb +22 -0
- data/lib/contrast/utils/resource_loader.rb +23 -0
- data/lib/contrast/utils/ruby_ast_rewriter.rb +74 -0
- data/lib/contrast/utils/scope_util.rb +99 -0
- data/lib/contrast/utils/service_response_util.rb +116 -0
- data/lib/contrast/utils/service_sender_util.rb +98 -0
- data/lib/contrast/utils/sha256_builder.rb +69 -0
- data/lib/contrast/utils/sinatra_helper.rb +49 -0
- data/lib/contrast/utils/stack_trace_utils.rb +209 -0
- data/lib/contrast/utils/string_utils.rb +72 -0
- data/lib/contrast/utils/tag_util.rb +139 -0
- data/lib/contrast/utils/thread_tracker.rb +54 -0
- data/lib/contrast/utils/timer.rb +78 -0
- data/resources/assess/policy.json +1673 -0
- data/resources/csrf/inject.js +44 -0
- data/resources/deadzone/policy.json +55 -0
- data/resources/factory-bot-spec/spec_helper.rb +30 -0
- data/resources/inventory/policy.json +110 -0
- data/resources/protect/policy.json +417 -0
- data/resources/rubocops/kernel/catch_cop.rb +37 -0
- data/resources/rubocops/kernel/require_cop.rb +37 -0
- data/resources/rubocops/kernel/require_relative_cop.rb +33 -0
- data/resources/rubocops/module/autoload_cop.rb +37 -0
- data/resources/rubocops/module/const_defined_cop.rb +37 -0
- data/resources/rubocops/module/const_get_cop.rb +37 -0
- data/resources/rubocops/module/const_set_cop.rb +37 -0
- data/resources/rubocops/module/constants_cop.rb +37 -0
- data/resources/rubocops/module/name_cop.rb +37 -0
- data/resources/rubocops/object/class_cop.rb +37 -0
- data/resources/rubocops/object/freeze_cop.rb +37 -0
- data/resources/rubocops/object/frozen_cop.rb +37 -0
- data/resources/rubocops/object/is_a_cop.rb +37 -0
- data/resources/rubocops/object/method_cop.rb +37 -0
- data/resources/rubocops/object/respond_to_cop.rb +37 -0
- data/resources/rubocops/object/singleton_class_cop.rb +37 -0
- data/resources/rubocops/regexp/spelling_cop.rb +44 -0
- data/resources/rubocops/thread/new_cop.rb +39 -0
- data/resources/ruby-spec/ancestors_spec.rb +70 -0
- data/resources/ruby-spec/modulo_spec.rb +831 -0
- data/resources/ruby-spec/parameters_spec.rb +261 -0
- data/resources/ruby-spec/ruby_spec_spec_helper.rb +35 -0
- data/resources/test_marker.txt +1 -0
- data/ruby-agent.gemspec +129 -0
- data/service_executables/.gitkeep +0 -0
- data/service_executables/VERSION +1 -0
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +945 -0
@@ -0,0 +1,94 @@
|
|
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
|
+
module Contrast
|
5
|
+
module Agent
|
6
|
+
module Patching
|
7
|
+
module Policy
|
8
|
+
# This class is used to map each method to the trigger node that applies to it
|
9
|
+
class MethodPolicy
|
10
|
+
attr_accessor :source_node, :propagation_node, :trigger_node,
|
11
|
+
:inventory_node, :protect_node, :deadzone_node,
|
12
|
+
:method_name, :method_visibility, :instance_method
|
13
|
+
def initialize(source_node: nil, propagation_node: nil,
|
14
|
+
trigger_node: nil, inventory_node: nil,
|
15
|
+
protect_node: nil, deadzone_node: nil,
|
16
|
+
method_name: nil, method_visibility: nil,
|
17
|
+
instance_method: nil)
|
18
|
+
@method_name = method_name
|
19
|
+
@method_visibility = method_visibility
|
20
|
+
@instance_method = instance_method
|
21
|
+
@source_node = source_node
|
22
|
+
@propagation_node = propagation_node
|
23
|
+
@trigger_node = trigger_node
|
24
|
+
@inventory_node = inventory_node
|
25
|
+
@protect_node = protect_node
|
26
|
+
@deadzone_node = deadzone_node
|
27
|
+
end
|
28
|
+
|
29
|
+
def private_method?
|
30
|
+
method_visibility == :private
|
31
|
+
end
|
32
|
+
|
33
|
+
def empty?
|
34
|
+
return false if source_node
|
35
|
+
return false if propagation_node
|
36
|
+
return false if trigger_node
|
37
|
+
return false if inventory_node
|
38
|
+
return false if protect_node
|
39
|
+
return false if deadzone_node
|
40
|
+
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
def requires_custom_patch?
|
45
|
+
!!@trigger_node&.custom_patch?
|
46
|
+
end
|
47
|
+
|
48
|
+
class << self
|
49
|
+
# Given a Contrast::Agent::Patching::Policy::ModulePolicy, parse
|
50
|
+
# out its information for the given method in order to construct a
|
51
|
+
# Contrast::Agent::Patching::Policy::MethodPolicy
|
52
|
+
#
|
53
|
+
# @param method_name [Symbol] the name of the method for this policy
|
54
|
+
# @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy]
|
55
|
+
# the entire policy for this module
|
56
|
+
# @param instance_method [Boolean] true if this method is an
|
57
|
+
# instance method
|
58
|
+
# @return [Contrast::Agent::Patching::Policy::MethodPolicy]
|
59
|
+
def build_method_policy method_name, module_policy, instance_method
|
60
|
+
source_node = find_method_node(module_policy.source_nodes, method_name, instance_method)
|
61
|
+
propagation_node = find_method_node(module_policy.propagator_nodes, method_name, instance_method)
|
62
|
+
trigger_node = find_method_node(module_policy.trigger_nodes, method_name, instance_method)
|
63
|
+
protect_node = find_method_node(module_policy.protect_nodes, method_name, instance_method)
|
64
|
+
inventory_node = find_method_node(module_policy.inventory_nodes, method_name, instance_method)
|
65
|
+
deadzone_node = find_method_node(module_policy.deadzone_nodes, method_name, instance_method)
|
66
|
+
method_visibility = find_visibility(source_node, propagation_node, trigger_node, protect_node, inventory_node, deadzone_node)
|
67
|
+
MethodPolicy.new(method_name: method_name,
|
68
|
+
method_visibility: method_visibility,
|
69
|
+
instance_method: instance_method,
|
70
|
+
source_node: source_node,
|
71
|
+
propagation_node: propagation_node,
|
72
|
+
trigger_node: trigger_node,
|
73
|
+
protect_node: protect_node,
|
74
|
+
inventory_node: inventory_node,
|
75
|
+
deadzone_node: deadzone_node)
|
76
|
+
end
|
77
|
+
|
78
|
+
def find_method_node nodes, method_name, is_instance_method
|
79
|
+
return nil unless nodes
|
80
|
+
|
81
|
+
nodes.find do |node|
|
82
|
+
node.instance_method? == is_instance_method && node.method_name == method_name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_visibility *nodes
|
87
|
+
nodes.find { |node| node }&.method_visibility
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
cs__scoped_require 'contrast/agent/patching/policy/method_policy'
|
5
|
+
|
6
|
+
module Contrast
|
7
|
+
module Agent
|
8
|
+
module Patching
|
9
|
+
module Policy
|
10
|
+
# This class is used to map a class to all policy nodes utilizing that
|
11
|
+
# class. It should be initialized using the create_module_policy method
|
12
|
+
# rather than new.
|
13
|
+
class ModulePolicy
|
14
|
+
class << self
|
15
|
+
# Given the name of a module, create a :ModulePolicy for it using
|
16
|
+
# the Policy of each supported feature
|
17
|
+
#
|
18
|
+
# @param module_name [String] the name of the module to which the
|
19
|
+
# policy applies
|
20
|
+
# @return [Contrast::Agent::Patching::Policy::ModulePolicy]
|
21
|
+
def create_module_policy module_name
|
22
|
+
module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.new
|
23
|
+
module_policy.source_nodes = nodes_for_module(Contrast::Agent::Assess::Policy::Policy.instance.sources, module_name)
|
24
|
+
module_policy.propagator_nodes = nodes_for_module(Contrast::Agent::Assess::Policy::Policy.instance.propagators, module_name)
|
25
|
+
module_policy.trigger_nodes = nodes_for_module(Contrast::Agent::Assess::Policy::Policy.instance.triggers, module_name)
|
26
|
+
module_policy.protect_nodes = nodes_for_module(Contrast::Agent::Protect::Policy::Policy.instance.triggers, module_name)
|
27
|
+
module_policy.inventory_nodes = nodes_for_module(Contrast::Agent::Inventory::Policy::Policy.instance.triggers, module_name)
|
28
|
+
module_policy.deadzone_nodes = nodes_for_module(Contrast::Agent::Deadzone::Policy::Policy.instance.deadzones, module_name)
|
29
|
+
module_policy
|
30
|
+
end
|
31
|
+
|
32
|
+
# Find any of the given patchers that match this class' names.
|
33
|
+
# Always returns an array, even if it's empty.
|
34
|
+
#
|
35
|
+
# @param nodes [Array(Contrast::Agent::Patching::Policy::PolicyNode)]
|
36
|
+
# an array of nodes
|
37
|
+
# @param class_name [String] the class to filter the nodes on
|
38
|
+
# @return [Array<Contrast::Agent::Patching::Policy::PolicyNode>]
|
39
|
+
# Subset of nodes which apply to the given class
|
40
|
+
def nodes_for_module nodes, class_name
|
41
|
+
nodes.select { |node| class_name == node.class_name }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
attr_accessor :source_nodes, :propagator_nodes, :trigger_nodes, :inventory_nodes, :protect_nodes, :deadzone_nodes
|
46
|
+
|
47
|
+
def empty?
|
48
|
+
return false if source_nodes.any?
|
49
|
+
return false if propagator_nodes.any?
|
50
|
+
return false if trigger_nodes.any?
|
51
|
+
return false if inventory_nodes.any?
|
52
|
+
return false if protect_nodes.any?
|
53
|
+
return false if deadzone_nodes.any?
|
54
|
+
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
# The number of expected patches for this policy is the sum of unique
|
59
|
+
# targeted methods for the Module to which this policy applies.
|
60
|
+
#
|
61
|
+
# @return [Integer] count of methods to be patched
|
62
|
+
def num_expected_patches
|
63
|
+
@_num_expected_patches ||= begin
|
64
|
+
instance_methods = Set.new
|
65
|
+
singleton_methods = Set.new
|
66
|
+
sort_method_names(source_nodes, instance_methods, singleton_methods)
|
67
|
+
sort_method_names(propagator_nodes, instance_methods, singleton_methods)
|
68
|
+
sort_method_names(trigger_nodes, instance_methods, singleton_methods)
|
69
|
+
sort_method_names(inventory_nodes, instance_methods, singleton_methods)
|
70
|
+
sort_method_names(protect_nodes, instance_methods, singleton_methods)
|
71
|
+
sort_method_names(deadzone_nodes, instance_methods, singleton_methods)
|
72
|
+
instance_methods.length + singleton_methods.length
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def collect_class_nodes nodes, clazz_name
|
77
|
+
return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless nodes
|
78
|
+
|
79
|
+
nodes.select { |policy_node| clazz_name == policy_node.class_name }
|
80
|
+
end
|
81
|
+
|
82
|
+
def collect_method_nodes nodes, method, instance_method
|
83
|
+
return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless nodes
|
84
|
+
|
85
|
+
nodes.select do |node|
|
86
|
+
node.instance_method? == instance_method && node.method_name == method
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_method_policy_subset method, instance_method
|
91
|
+
method_policy = ModulePolicy.new
|
92
|
+
method_policy.source_nodes = collect_method_nodes(source_nodes, method, instance_method)
|
93
|
+
method_policy.propagator_nodes = collect_method_nodes(propagator_nodes, method, instance_method)
|
94
|
+
method_policy.trigger_nodes = collect_method_nodes(trigger_nodes, method, instance_method)
|
95
|
+
method_policy.inventory_nodes = collect_method_nodes(inventory_nodes, method, instance_method)
|
96
|
+
method_policy.protect_nodes = collect_method_nodes(protect_nodes, method, instance_method)
|
97
|
+
method_policy.deadzone_nodes = collect_method_nodes(deadzone_nodes, method, instance_method)
|
98
|
+
method_policy
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def sort_method_names nodes, instance_methods, singleton_methods
|
104
|
+
nodes.each do |node|
|
105
|
+
if node.instance_method?
|
106
|
+
instance_methods << node.method_name
|
107
|
+
else
|
108
|
+
singleton_methods << node.method_name
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,312 @@
|
|
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 'monitor'
|
5
|
+
# base
|
6
|
+
cs__scoped_require 'contrast/core_extensions/module'
|
7
|
+
cs__scoped_require 'contrast/agent/patching/policy/method_policy'
|
8
|
+
cs__scoped_require 'contrast/agent/patching/policy/patch_status'
|
9
|
+
cs__scoped_require 'contrast/agent/patching/policy/trigger_node'
|
10
|
+
cs__scoped_require 'contrast/components/interface'
|
11
|
+
cs__scoped_require 'contrast/utils/scope_util'
|
12
|
+
|
13
|
+
# assess
|
14
|
+
cs__scoped_require 'contrast/agent/assess/policy/policy'
|
15
|
+
cs__scoped_require 'contrast/agent/assess/policy/propagation_method'
|
16
|
+
cs__scoped_require 'contrast/agent/assess/policy/source_method'
|
17
|
+
cs__scoped_require 'contrast/agent/assess/policy/trigger_method'
|
18
|
+
cs__scoped_require 'contrast/core_extensions/assess'
|
19
|
+
|
20
|
+
# inventory
|
21
|
+
cs__scoped_require 'contrast/agent/inventory/policy/policy'
|
22
|
+
cs__scoped_require 'contrast/core_extensions/inventory'
|
23
|
+
|
24
|
+
# protect
|
25
|
+
cs__scoped_require 'contrast/agent/protect/policy/policy'
|
26
|
+
cs__scoped_require 'contrast/core_extensions/protect'
|
27
|
+
cs__scoped_require 'contrast/core_extensions/protect/kernel'
|
28
|
+
|
29
|
+
module Contrast
|
30
|
+
module Agent
|
31
|
+
module Patching
|
32
|
+
module Policy
|
33
|
+
# This is how we patch into our customer's code. It provides a way to
|
34
|
+
# track which classes we need to patch into and, once we've woven,
|
35
|
+
# provides a map for which methods our renamed functions need to call
|
36
|
+
# and how.
|
37
|
+
module Patch
|
38
|
+
class << self
|
39
|
+
include Contrast::Agent::Assess::Policy::SourceMethod
|
40
|
+
include Contrast::Agent::Assess::Policy::PropagationMethod
|
41
|
+
include Contrast::Agent::Assess::Policy::TriggerMethod
|
42
|
+
extend Contrast::Utils::ScopeUtil
|
43
|
+
|
44
|
+
include Contrast::Components::Interface
|
45
|
+
access_component :logging, :analysis, :agent, :scope
|
46
|
+
|
47
|
+
POLICIES = [
|
48
|
+
Contrast::Agent::Assess::Policy::Policy,
|
49
|
+
Contrast::Agent::Inventory::Policy::Policy,
|
50
|
+
Contrast::Agent::Protect::Policy::Policy
|
51
|
+
].cs__freeze
|
52
|
+
|
53
|
+
# THIS IS CALLED FROM C. Do not change the signature lightly.
|
54
|
+
#
|
55
|
+
# This method functions to call the infilter methods from our
|
56
|
+
# patches, allowing for analysis and reporting at the point just
|
57
|
+
# before the patched code is invoked.
|
58
|
+
#
|
59
|
+
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
60
|
+
# Mapping of the triggers on the given method.
|
61
|
+
# @param method [Symbol] The method into which we're patching
|
62
|
+
# @param exception [StandardError] Any exception raised during the
|
63
|
+
# call of the patched method.
|
64
|
+
# @param object [Object] The object on which the method is invoked,
|
65
|
+
# typically what would be returned by self.
|
66
|
+
# @param args [Array<Object>] The arguments passed to the method
|
67
|
+
# being invoked.
|
68
|
+
def apply_pre_patch method_policy, method, exception, object, args
|
69
|
+
apply_protect(method_policy, method, exception, object, args)
|
70
|
+
apply_inventory(method_policy, method, exception, object, args)
|
71
|
+
# We were told to block something, so we gotta. Don't catch this
|
72
|
+
# one, let it get back to our Middleware or even all the way out to
|
73
|
+
# the framework
|
74
|
+
rescue Contrast::SecurityException => e
|
75
|
+
# This can be C's responsibility, but it's a lot of code.
|
76
|
+
# Rewrite this to make C do it, once we have better macroing.
|
77
|
+
exit_contrast_scope!
|
78
|
+
raise e
|
79
|
+
# Anything else was our bad and we gotta catch that to allow for
|
80
|
+
# normal application flow
|
81
|
+
rescue StandardError => e
|
82
|
+
logger.error(e, 'Unable to apply pre patch to method.')
|
83
|
+
end
|
84
|
+
|
85
|
+
# THIS IS CALLED FROM C. Do not change the signature lightly.
|
86
|
+
#
|
87
|
+
# This method functions to call the infilter methods from our
|
88
|
+
# patches, allowing for analysis and reporting at the point just
|
89
|
+
# after the patched code is invoked
|
90
|
+
#
|
91
|
+
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
92
|
+
# Mapping of the triggers on the given method.
|
93
|
+
# @param preshift [Contrast::Agent::Assess::PreShift] The capture
|
94
|
+
# of the state of the code just prior to the invocation of the
|
95
|
+
# patched method.
|
96
|
+
# @param object [Object] The object on which the method was
|
97
|
+
# invoked, typically what would be returned by self.
|
98
|
+
# @param ret [Object] The return of the method that was invoked.
|
99
|
+
# @param args [Array<Object>] The arguments passed to the method
|
100
|
+
# being invoked.
|
101
|
+
# @param block [Proc] The block passed to the method that was
|
102
|
+
# invoked.
|
103
|
+
def apply_post_patch method_policy, preshift, object, ret, args, block
|
104
|
+
apply_assess(method_policy, preshift, object, ret, args, block)
|
105
|
+
rescue StandardError => e
|
106
|
+
logger.error(e, 'Unable to apply post patch to method.')
|
107
|
+
end
|
108
|
+
|
109
|
+
# Apply the Protect patch which applies to the given method.
|
110
|
+
#
|
111
|
+
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
112
|
+
# Mapping of the triggers on the given method.
|
113
|
+
# @param method [Symbol] The method into which we're patching
|
114
|
+
# @param exception [StandardError] Any exception raised during the
|
115
|
+
# call of the patched method.
|
116
|
+
# @param object [Object] The object on which the method is invoked,
|
117
|
+
# typically what would be returned by self.
|
118
|
+
# @param args [Array<Object>] The arguments passed to the method
|
119
|
+
# being invoked.
|
120
|
+
def apply_protect method_policy, method, exception, object, args
|
121
|
+
return unless PROTECT.enabled?
|
122
|
+
|
123
|
+
apply_trigger_only(method_policy&.protect_node,
|
124
|
+
method,
|
125
|
+
exception,
|
126
|
+
object,
|
127
|
+
args)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Apply the Inventory patch which applies to the given method.
|
131
|
+
#
|
132
|
+
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
133
|
+
# Mapping of the triggers on the given method.
|
134
|
+
# @param method [Symbol] The method into which we're patching
|
135
|
+
# @param exception [StandardError] Any exception raised during the
|
136
|
+
# call of the patched method.
|
137
|
+
# @param object [Object] The object on which the method is invoked,
|
138
|
+
# typically what would be returned by self.
|
139
|
+
# @param args [Array<Object>] The arguments passed to the method
|
140
|
+
# being invoked.
|
141
|
+
def apply_inventory method_policy, method, exception, object, args
|
142
|
+
return unless INVENTORY.enabled?
|
143
|
+
|
144
|
+
apply_trigger_only(method_policy&.inventory_node,
|
145
|
+
method,
|
146
|
+
exception,
|
147
|
+
object,
|
148
|
+
args)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Apply the Assess patches which apply to the given method.
|
152
|
+
#
|
153
|
+
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
154
|
+
# Mapping of the triggers on the given method.
|
155
|
+
# @param preshift [Contrast::Agent::Assess::PreShift] The capture
|
156
|
+
# of the state of the code just prior to the invocation of the
|
157
|
+
# patched method.
|
158
|
+
# @param object [Object] The object on which the method was
|
159
|
+
# invoked, typically what would be returned by self.
|
160
|
+
# @param ret [Object] The return of the method that was invoked.
|
161
|
+
# @param args [Array<Object>] The arguments passed to the method
|
162
|
+
# being invoked.
|
163
|
+
# @param block [Proc] The block passed to the method that was
|
164
|
+
# invoked.
|
165
|
+
def apply_assess method_policy, preshift, object, ret, args, block
|
166
|
+
source_ret = nil
|
167
|
+
propagated_ret = nil
|
168
|
+
return ret unless method_policy && ASSESS.enabled?
|
169
|
+
|
170
|
+
current_context = Contrast::Agent::REQUEST_TRACKER.current
|
171
|
+
return ret unless current_context.analyze_request?
|
172
|
+
|
173
|
+
trigger_node = method_policy.trigger_node
|
174
|
+
Contrast::Agent::Assess::Policy::TriggerMethod.apply_trigger_rule(trigger_node, object, ret, args) if trigger_node
|
175
|
+
|
176
|
+
if method_policy.source_node
|
177
|
+
# If we were given a frozen return, and it was the target of a
|
178
|
+
# source, and we have frozen sources enabled, we'll need to
|
179
|
+
# replace the return. Note, this is not the default case.
|
180
|
+
source_ret = Contrast::Agent::Assess::Policy::SourceMethod.source_patchers(method_policy, object, ret, args)
|
181
|
+
end
|
182
|
+
|
183
|
+
if method_policy.propagation_node
|
184
|
+
propagated_ret = Contrast::Agent::Assess::Policy::PropagationMethod.apply_propagation(
|
185
|
+
method_policy,
|
186
|
+
preshift,
|
187
|
+
object,
|
188
|
+
source_ret || ret,
|
189
|
+
args,
|
190
|
+
block)
|
191
|
+
end
|
192
|
+
|
193
|
+
handle_return(propagated_ret, source_ret, ret)
|
194
|
+
rescue StandardError => e
|
195
|
+
logger.error(e, 'Unable to assess method call.')
|
196
|
+
handle_return(propagated_ret, source_ret, ret)
|
197
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
198
|
+
logger.error(e, 'Unable to assess method call.')
|
199
|
+
handle_return(propagated_ret, source_ret, ret)
|
200
|
+
# This will unwind the stack, so we handle our own scope exit.
|
201
|
+
# Move this to C when it's convenient.
|
202
|
+
exit_contrast_scope!
|
203
|
+
raise e
|
204
|
+
end
|
205
|
+
|
206
|
+
# Generic invocation of the Inventory or Protect patch which apply
|
207
|
+
# to the given method.
|
208
|
+
#
|
209
|
+
# @param trigger_node [Contrast::Agent::Inventory::Policy::TriggerNode]
|
210
|
+
# Mapping of the specific trigger on the given method.
|
211
|
+
# @param method [Symbol] The method into which we're patching
|
212
|
+
# @param exception [StandardError] Any exception raised during the
|
213
|
+
# call of the patched method.
|
214
|
+
# @param object [Object] The object on which the method is invoked,
|
215
|
+
# typically what would be returned by self.
|
216
|
+
# @param args [Array<Object>] The arguments passed to the method
|
217
|
+
# being invoked.
|
218
|
+
def apply_trigger_only trigger_node, method, exception, object, args
|
219
|
+
return unless trigger_node
|
220
|
+
|
221
|
+
# If that rule only applies in the case of an exception being
|
222
|
+
# thrown and there's no exception here, move along, or vice versa
|
223
|
+
return if trigger_node.on_exception && !exception
|
224
|
+
return if !trigger_node.on_exception && exception
|
225
|
+
|
226
|
+
# Each patch has an applicator that handles logic for it. Think
|
227
|
+
# of this as being similar to propagator actions, most closely
|
228
|
+
# resembling CUSTOM - they all have a common interface but their
|
229
|
+
# own logic based on what's in the method(s) they've been patched
|
230
|
+
# into.
|
231
|
+
applicator = trigger_node.applicator
|
232
|
+
# Each patch also knows the method of its applicator. Some
|
233
|
+
# things, like AppliesXxeRule, have different methods depending
|
234
|
+
# on the library patched. This lets us handle the boilerplate of
|
235
|
+
# patching while still allowing for custom handling of the
|
236
|
+
# methods.
|
237
|
+
applicator_method = trigger_node.applicator_method
|
238
|
+
# By calling send like this, we can reuse all the patching.
|
239
|
+
# We `send` to the given method of the given class
|
240
|
+
# (applicator) since they all accept the same inputs
|
241
|
+
applicator.send(applicator_method, method, exception, trigger_node.properties, object, args)
|
242
|
+
end
|
243
|
+
|
244
|
+
# Method to choose which replaced return from the post_patch to
|
245
|
+
# actually return
|
246
|
+
#
|
247
|
+
# @param propagated_ret [Object, nil] The replaced return from the
|
248
|
+
# propagation patch.
|
249
|
+
# @param source_ret [Object, nil] The replaced return from the
|
250
|
+
# source patch.
|
251
|
+
# @param ret [Object, nil] The original return of the patched
|
252
|
+
# method.
|
253
|
+
# @return [Object, nil] The thing to return from the post patch.
|
254
|
+
def handle_return propagated_ret, source_ret, ret
|
255
|
+
safe_return = propagated_ret || source_ret || ret
|
256
|
+
safe_return.rewind if Contrast::Utils::IOUtil.should_rewind?(safe_return)
|
257
|
+
safe_return
|
258
|
+
end
|
259
|
+
|
260
|
+
# Given a class, method, and type, return a symbol in the format
|
261
|
+
# <method_start>_<class_name>_<method_name>
|
262
|
+
def build_method_name patcher_class, patcher_method
|
263
|
+
(Contrast::Utils::ObjectShare::CONTRAST_PATCHED_METHOD_START +
|
264
|
+
patcher_class.cs__name.gsub('::', '_').downcase +
|
265
|
+
Contrast::Utils::ObjectShare::UNDERSCORE +
|
266
|
+
patcher_method.to_s).to_sym
|
267
|
+
end
|
268
|
+
|
269
|
+
# @param mod [Module] the module in which the patch should be
|
270
|
+
# placed.
|
271
|
+
# @param methods [Array(Symbol)] all the instance or singleton
|
272
|
+
# methods in this clazz.
|
273
|
+
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
274
|
+
# the policy that applies to the method to be patched.
|
275
|
+
# @return [Boolean] if patched, either by this invocation or a
|
276
|
+
# previous, or not
|
277
|
+
def instrument_with_alias mod, methods, method_policy
|
278
|
+
cs_method_name = build_method_name(mod, method_policy.method_name)
|
279
|
+
# we've already patched this class, don't do it again
|
280
|
+
return true if methods.include?(cs_method_name)
|
281
|
+
|
282
|
+
begin
|
283
|
+
contrast_define_method(mod, method_policy, cs_method_name)
|
284
|
+
rescue NameError => e
|
285
|
+
# This shouldn't happen anymore, but just in case calling alias
|
286
|
+
# results in a NameError, we'll be safe here.
|
287
|
+
logger.debug(
|
288
|
+
e,
|
289
|
+
"The class #{ mod.cs__name } does not respond to the "\
|
290
|
+
"method#{ method_policy.method_name }.")
|
291
|
+
return false
|
292
|
+
end
|
293
|
+
true
|
294
|
+
end
|
295
|
+
|
296
|
+
# @param mod [Module] the module in which the patch should be
|
297
|
+
# placed.
|
298
|
+
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
299
|
+
# the policy that applies to the method to be patched.
|
300
|
+
# @return [Boolean] if patched, either by this invocation or a
|
301
|
+
# previous, or not
|
302
|
+
def instrument_with_prepend mod, method_policy
|
303
|
+
contrast_prepend_method(mod, method_policy)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
cs__scoped_require 'cs__contrast_patch/cs__contrast_patch'
|