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,135 @@
|
|
|
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/boolean_util'
|
|
5
|
+
cs__scoped_require 'contrast/utils/env_configuration_item'
|
|
6
|
+
cs__scoped_require 'contrast/configuration'
|
|
7
|
+
|
|
8
|
+
module Contrast
|
|
9
|
+
module Components
|
|
10
|
+
# This component encapsulates reference to the configuration file.
|
|
11
|
+
# At the time of writing, the configuration file is a yaml file reflecting
|
|
12
|
+
# the 'common agent configuration' specification.
|
|
13
|
+
# 'Config' and 'configuration' are to be interpreted as referring
|
|
14
|
+
# specifically to these files and specifications, they are not generic
|
|
15
|
+
# terms for other avenues of user configuration.
|
|
16
|
+
#
|
|
17
|
+
# This component is responsible for...
|
|
18
|
+
# - encapsulating file access & concomitant error conditions
|
|
19
|
+
# - implementing validity checks with respect to the specification
|
|
20
|
+
# - memoizing/streamline field accesses
|
|
21
|
+
#
|
|
22
|
+
# Config fails fast. if it's not valid, the agent should break, and
|
|
23
|
+
# it should break LOUDLY. Better to waste half an hour of the sysadmin's
|
|
24
|
+
# time than to silently fail to deliver functionality.
|
|
25
|
+
module Config
|
|
26
|
+
LOG_CONFIGURATION_DISABLED = 'Contrast disabled by configuration. Continuing without instrumentation.'
|
|
27
|
+
CONTRAST_ENV_MARKER = 'CONTRAST__'
|
|
28
|
+
|
|
29
|
+
class Interface # :nodoc:
|
|
30
|
+
def initialize
|
|
31
|
+
build
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def build log: true
|
|
35
|
+
@_valid = nil
|
|
36
|
+
@config = Contrast::Configuration.new
|
|
37
|
+
defaults
|
|
38
|
+
overrides
|
|
39
|
+
validate(log: log)
|
|
40
|
+
end
|
|
41
|
+
alias_method :rebuild, :build
|
|
42
|
+
|
|
43
|
+
# Prefer abstraction, but use #raw if you need.
|
|
44
|
+
# grep 'CONFIG.raw' for opportunities to refactor.
|
|
45
|
+
def raw
|
|
46
|
+
@config
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def root
|
|
50
|
+
raw.root
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def enabled?
|
|
54
|
+
Contrast::Utils::BooleanUtil.true?(raw.enable)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def disabled?
|
|
58
|
+
!enabled?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def protect?
|
|
62
|
+
Contrast::Utils::BooleanUtil.true?(raw.protect.enable)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def assess?
|
|
66
|
+
Contrast::Utils::BooleanUtil.true?(raw.assess.enable)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def session_id
|
|
70
|
+
@_session_id ||= begin
|
|
71
|
+
s = raw.application.session_id || ''
|
|
72
|
+
s.empty? ? nil : s
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def session_metadata
|
|
77
|
+
@_session_metadata ||= begin
|
|
78
|
+
s = raw.application.session_metadata || ''
|
|
79
|
+
s.empty? ? nil : s
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def valid?
|
|
84
|
+
@_valid = validate(log: false) if @_valid.nil?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def invalid?
|
|
88
|
+
!valid?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
SESSION_VARIABLES = "Invalid configuration. Setting both application.session_id and application.session_metadata is not allowed.\n"
|
|
94
|
+
def validate log: false
|
|
95
|
+
# The config has information about how to construct the logger.
|
|
96
|
+
# If the config is invalid, and you want to know about it, then
|
|
97
|
+
# you have a circular dependency if you try to log it,
|
|
98
|
+
# hence `log: false`.
|
|
99
|
+
if session_id && session_metadata
|
|
100
|
+
if log
|
|
101
|
+
cs__class.log_error(SESSION_VARIABLES)
|
|
102
|
+
else
|
|
103
|
+
puts SESSION_VARIABLES
|
|
104
|
+
end
|
|
105
|
+
return false
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
true
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def defaults
|
|
112
|
+
raw.agent.service.host ||= Contrast::Configuration::DEFAULT_HOST
|
|
113
|
+
raw.agent.service.port ||= Contrast::Configuration::DEFAULT_PORT
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def overrides
|
|
117
|
+
env_overrides
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def env_overrides
|
|
121
|
+
# For env variables resembling CONTRAST__WHATEVER__NESTED_VALUE
|
|
122
|
+
# override raw.whatever.nested_value
|
|
123
|
+
ENV.each do |env_key, env_value|
|
|
124
|
+
next unless env_key.to_s.start_with?(CONTRAST_ENV_MARKER)
|
|
125
|
+
|
|
126
|
+
config_item = Contrast::Utils::EnvConfigurationItem.new(env_key, env_value)
|
|
127
|
+
raw.assign_value_to_path_array(config_item.dot_path_array, config_item.value)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
COMPONENT_INTERFACE = Interface.new
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
cs__scoped_require 'monitor'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Components
|
|
8
|
+
module ContrastService
|
|
9
|
+
# A wrapper build around the Common Agent Configuration project to allow
|
|
10
|
+
# for access of the values contained in its
|
|
11
|
+
# parent_configuration_spec.yaml.
|
|
12
|
+
# Specifically, this allows for querying the state of the connection to
|
|
13
|
+
# the Service, as well as sending a message to the Service.
|
|
14
|
+
class Interface
|
|
15
|
+
include Contrast::Components::ComponentBase
|
|
16
|
+
include Contrast::Components::Interface
|
|
17
|
+
|
|
18
|
+
access_component :config, :agent
|
|
19
|
+
|
|
20
|
+
def update_received?
|
|
21
|
+
state.update_received?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def enabled?
|
|
25
|
+
state.service_enabled?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def unavailable?
|
|
29
|
+
!enabled?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def disabled?
|
|
33
|
+
state.service_forcibly_disabled?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def host
|
|
37
|
+
@_host ||= (CONFIG.root.agent.service.host || Contrast::Configuration::DEFAULT_HOST).to_s
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def port
|
|
41
|
+
@_port ||= (CONFIG.root.agent.service.port || Contrast::Configuration::DEFAULT_PORT).to_i
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def socket_path
|
|
45
|
+
@_socket_path ||= CONFIG.root.agent.service.socket
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def logger_path
|
|
49
|
+
@_logger_path ||= CONFIG.root.agent.service.logger.path || DEFAULT_LOG_FILENAME
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def use_tcp?
|
|
53
|
+
socket_path.nil?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def last_update
|
|
57
|
+
state.last_update
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def use_bundled_service?
|
|
61
|
+
# Validates the config to decide if it's suitable for starting
|
|
62
|
+
# the bundled service
|
|
63
|
+
@_use_bundled_service ||= begin
|
|
64
|
+
# Requirement says "must be true" but that
|
|
65
|
+
# should be "must not be false" -- oops.
|
|
66
|
+
!false?(CONFIG.root.agent.start_bundled_service) &&
|
|
67
|
+
# Either a valid host or a valid socket
|
|
68
|
+
(CONFIG.root.agent.service.host.nil? ||
|
|
69
|
+
CONFIG.root.agent.service.host == 'localhost' ||
|
|
70
|
+
CONFIG.root.agent.service.host == '127.0.0.1' ||
|
|
71
|
+
CONFIG.root.agent.service.host.empty?) ||
|
|
72
|
+
# Path validity is the service's problem
|
|
73
|
+
!CONFIG.root.agent.service.socket.empty?
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# TODO: As part of RUBY-356. Add new handling for SQL analysis via RPC (SPEED-211)
|
|
78
|
+
|
|
79
|
+
# The API for Agent to Service communication. These methods abstract away implementation
|
|
80
|
+
# details, responsibilities of sending messages to the service, and requirements mandated
|
|
81
|
+
# within the Agent<>SpeedRacer contract.
|
|
82
|
+
|
|
83
|
+
# Pushes a message onto a queue to later be consumed when the service sender thread is ready to
|
|
84
|
+
# handle it. The service response is not returned; rather, it is processed by the service sender
|
|
85
|
+
# thread. All messages sent to SpeedRacer should be queued rather than sent unless the calling method
|
|
86
|
+
# explicitly needs to act on the response object with custom logic (i.e. RequestContext#service_extract_response)
|
|
87
|
+
# @param msg [Contrast::Api::Dtm::Message] the message to be sent
|
|
88
|
+
def queue_message msg
|
|
89
|
+
return unless msg
|
|
90
|
+
|
|
91
|
+
Contrast::Utils::ServiceSenderUtil.push_to_ready_queue(msg)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# TODO: RUBY-662. Add additional check before we queue/send a message to see if we were unable
|
|
95
|
+
# to connect to the service.
|
|
96
|
+
|
|
97
|
+
# Bypass the queue and send the message directly to SpeedRacer. This is the only way
|
|
98
|
+
# to receive the response object back from SpeedRacer. An invoking method that needs
|
|
99
|
+
# to process the response object with custom logic should use this method.
|
|
100
|
+
#
|
|
101
|
+
# @param msg [Contrast::Api::Dtm::Message] the message to be sent
|
|
102
|
+
# @return [Array<Contrast::Api::Dtm::AttackResult>] the response from SpeedRacer
|
|
103
|
+
def send_message msg
|
|
104
|
+
return unless msg
|
|
105
|
+
|
|
106
|
+
state.client.send_to_speedracer(msg)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
COMPONENT_INTERFACE = Interface.new
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
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 Components
|
|
6
|
+
module HeapDump
|
|
7
|
+
# A wrapper build around the Common Agent Configuration project to allow
|
|
8
|
+
# for access of the values contained in its
|
|
9
|
+
# parent_configuration_spec.yaml.
|
|
10
|
+
# Specifically, this allows for querying the state of the Heap Dump
|
|
11
|
+
# utility.
|
|
12
|
+
module ClassMethods
|
|
13
|
+
include Contrast::Components::ComponentBase
|
|
14
|
+
include Contrast::Components::Interface
|
|
15
|
+
|
|
16
|
+
access_component :config
|
|
17
|
+
|
|
18
|
+
def heap_dump_enabled?
|
|
19
|
+
state.heap_dump_enabled?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def heap_dump_control
|
|
23
|
+
{
|
|
24
|
+
path: File.absolute_path(CONFIG.root.agent.heap_dump.path),
|
|
25
|
+
count: CONFIG.root.agent.heap_dump.count.to_i,
|
|
26
|
+
window: CONFIG.root.agent.heap_dump.window_ms.to_f / 1000,
|
|
27
|
+
delay: CONFIG.root.agent.heap_dump.delay_ms.to_f / 1000,
|
|
28
|
+
clean: true?(CONFIG.root.agent.heap_dump.clean)
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
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 'delegate'
|
|
5
|
+
cs__scoped_require 'contrast/core_extensions/module'
|
|
6
|
+
cs__scoped_require 'contrast/utils/boolean_util'
|
|
7
|
+
|
|
8
|
+
module Contrast
|
|
9
|
+
# This is the base module for our components classes. It is intended to
|
|
10
|
+
# facilitate the translation of the Common Configuration settings to usable
|
|
11
|
+
# Ruby methods. Any class under this namespace should be required here,
|
|
12
|
+
# providing a single point of require for this functionality.
|
|
13
|
+
module Components
|
|
14
|
+
# Include this into your classes and modules,
|
|
15
|
+
# and use 'access_component' to define constants that will allow
|
|
16
|
+
# interaction with other components.
|
|
17
|
+
module Interface
|
|
18
|
+
def self.included klass
|
|
19
|
+
# Upon inclusion, ComponentInterfaces extends the including with
|
|
20
|
+
# these two interfaces.
|
|
21
|
+
# Interface provides a class-level method 'access_component'
|
|
22
|
+
# that regulates per-class access to agent state.
|
|
23
|
+
# (It's a glorified `include MyComponent`).
|
|
24
|
+
klass.extend Contrast::Components::ComponentReceiverClassInterface
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# All component access is gated through delegators.
|
|
29
|
+
#
|
|
30
|
+
# One delegator is used by the calling class,
|
|
31
|
+
# so we can tweak outgoing calls.
|
|
32
|
+
#
|
|
33
|
+
# The second delegator is used by the receiving component,
|
|
34
|
+
# so we can tweak incoming calls.
|
|
35
|
+
#
|
|
36
|
+
# We use __setobj__ to decide which component implementation to use.
|
|
37
|
+
# This is intended to provide flexibility in design and
|
|
38
|
+
# simplicity in testing.
|
|
39
|
+
class ComponentDelegator < SimpleDelegator
|
|
40
|
+
# intentionally left blank
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# All components should inherit from this,
|
|
44
|
+
# whether Interfaces, InstanceMethods or ClassMethods.
|
|
45
|
+
module ComponentBase
|
|
46
|
+
def self.included klass
|
|
47
|
+
klass.extend Methods
|
|
48
|
+
klass.include Methods
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
module Methods # :nodoc:
|
|
52
|
+
def false? config_param
|
|
53
|
+
Contrast::Utils::BooleanUtil.false?(config_param)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def true? config_param
|
|
57
|
+
Contrast::Utils::BooleanUtil.true?(config_param)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# TODO: RUBY-536
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def _state_shim
|
|
64
|
+
Contrast::Agent::FeatureState.instance
|
|
65
|
+
end
|
|
66
|
+
alias_method :state, :_state_shim
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.component_const_name mod_name
|
|
71
|
+
mod_name = mod_name.split('::').last
|
|
72
|
+
@cache ||= {}
|
|
73
|
+
@cache[mod_name] ||= mod_name. # CamelCaseName
|
|
74
|
+
split(/(?=[A-Z])/)&. # ['Camel', 'Case', 'Name']
|
|
75
|
+
map(&:upcase)&. # ['CAMEL', 'CASE', 'NAME']
|
|
76
|
+
join('_') # 'CAMEL_CASE_NAME'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Interface to allow for iteration over each of the configuration
|
|
80
|
+
# components
|
|
81
|
+
module ComponentReceiverClassInterface
|
|
82
|
+
# Components are manually required at the end of
|
|
83
|
+
# this file, and this constant is then frozen.
|
|
84
|
+
# RUBY-535 to handle this better.
|
|
85
|
+
COMPONENT_MAP = {} # rubocop:disable Style/MutableConstant
|
|
86
|
+
|
|
87
|
+
# TODO: RUBY-535
|
|
88
|
+
# This module is used via `extend`, so it can't access
|
|
89
|
+
# constants we define here.
|
|
90
|
+
def component_map
|
|
91
|
+
COMPONENT_MAP
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# .access_component
|
|
95
|
+
#
|
|
96
|
+
# to be used as:
|
|
97
|
+
#
|
|
98
|
+
# class Abc
|
|
99
|
+
# include Contrast::Components::Interface
|
|
100
|
+
# access_component :logger, :agent
|
|
101
|
+
#
|
|
102
|
+
# def function
|
|
103
|
+
# if AGENT.disabled?
|
|
104
|
+
# 0 / 3
|
|
105
|
+
# end
|
|
106
|
+
# rescue
|
|
107
|
+
# logger.error "this function did error"
|
|
108
|
+
# end
|
|
109
|
+
# end
|
|
110
|
+
#
|
|
111
|
+
# `:logger` creates a #logger and .logger method
|
|
112
|
+
# `:agent` provides an AGENT constant, analogous to a local singleton.
|
|
113
|
+
#
|
|
114
|
+
def access_component *component_set_syms
|
|
115
|
+
@_access_component ||= {}
|
|
116
|
+
|
|
117
|
+
component_set_syms.each do |sym|
|
|
118
|
+
next if @_access_component[sym]
|
|
119
|
+
|
|
120
|
+
if (mods = component_map[sym]) # rubocop:disable Style/GuardClause
|
|
121
|
+
# We may support multiple components via one access request.
|
|
122
|
+
mods.each do |m|
|
|
123
|
+
name = Contrast::Components.component_const_name(m.name)
|
|
124
|
+
cs__const_set(name, m::COMPONENT_INTERFACE) if m.cs__const_defined?(:COMPONENT_INTERFACE)
|
|
125
|
+
include m::InstanceMethods if m.cs__const_defined?(:InstanceMethods, false)
|
|
126
|
+
extend m::ClassMethods if m.cs__const_defined?(:ClassMethods, false)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
@_access_component[sym] = true
|
|
130
|
+
else
|
|
131
|
+
raise NotImplementedError, "#{ self } asked to access undefined component '#{ sym }'."
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Components can depend on other components, but it should be a
|
|
140
|
+
# directed acyclic graph.
|
|
141
|
+
|
|
142
|
+
# Scope shouldn't depend on anything.
|
|
143
|
+
cs__scoped_require 'contrast/components/scope'
|
|
144
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:scope] = [Contrast::Components::Scope]
|
|
145
|
+
|
|
146
|
+
# Config depends on Scope.
|
|
147
|
+
cs__scoped_require 'contrast/components/config'
|
|
148
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:config] = [Contrast::Components::Config]
|
|
149
|
+
|
|
150
|
+
# Settings should not depend on anything but Config.
|
|
151
|
+
cs__scoped_require 'contrast/components/settings'
|
|
152
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:settings] = [Contrast::Components::Settings]
|
|
153
|
+
|
|
154
|
+
cs__scoped_require 'contrast/components/agent'
|
|
155
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:agent] = [Contrast::Components::Agent]
|
|
156
|
+
|
|
157
|
+
cs__scoped_require 'contrast/components/app_context'
|
|
158
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:app_context] = [Contrast::Components::AppContext]
|
|
159
|
+
|
|
160
|
+
cs__scoped_require 'contrast/components/contrast_service'
|
|
161
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:contrast_service] = [Contrast::Components::ContrastService]
|
|
162
|
+
|
|
163
|
+
cs__scoped_require 'contrast/components/heap_dump'
|
|
164
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:heap_dump] = [Contrast::Components::HeapDump]
|
|
165
|
+
|
|
166
|
+
cs__scoped_require 'contrast/components/logger'
|
|
167
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:logging] = [Contrast::Components::Logger]
|
|
168
|
+
|
|
169
|
+
cs__scoped_require 'contrast/components/assess'
|
|
170
|
+
cs__scoped_require 'contrast/components/protect'
|
|
171
|
+
cs__scoped_require 'contrast/components/inventory'
|
|
172
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:analysis] = [Contrast::Components::Protect,
|
|
173
|
+
Contrast::Components::Assess,
|
|
174
|
+
Contrast::Components::Inventory]
|
|
175
|
+
cs__scoped_require 'contrast/components/sampling'
|
|
176
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP[:sampling] = [Contrast::Components::Sampling]
|
|
177
|
+
|
|
178
|
+
Contrast::Components::ComponentReceiverClassInterface::COMPONENT_MAP.cs__freeze
|