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,96 @@
|
|
|
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 'singleton'
|
|
5
|
+
cs__scoped_require 'contrast/components/interface'
|
|
6
|
+
|
|
7
|
+
module Contrast
|
|
8
|
+
module Utils
|
|
9
|
+
module Assess
|
|
10
|
+
# SamplingUtil has methods for tracking the number of requests per time window
|
|
11
|
+
class SamplingUtil
|
|
12
|
+
include Singleton
|
|
13
|
+
|
|
14
|
+
include Contrast::Components::Interface
|
|
15
|
+
access_component :sampling
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@requests = {}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def update
|
|
22
|
+
@enabled = self.class.sampling_control[:enabled]
|
|
23
|
+
@baseline = self.class.sampling_control[:baseline]
|
|
24
|
+
@request_frequency = self.class.sampling_control[:request_frequency]
|
|
25
|
+
@response_frequency = self.class.sampling_control[:response_frequency]
|
|
26
|
+
@window_ms = self.class.sampling_control[:window]
|
|
27
|
+
|
|
28
|
+
true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def reset
|
|
32
|
+
@requests.clear
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def sample? request
|
|
36
|
+
history = request_history(request)
|
|
37
|
+
history.hit
|
|
38
|
+
|
|
39
|
+
# if sampling isn't enabled, we record all requests and take a
|
|
40
|
+
# default amount of responses
|
|
41
|
+
return [true, true] unless @enabled
|
|
42
|
+
|
|
43
|
+
# if we've exceeded this sample window, reset it
|
|
44
|
+
if history.elapsed >= @window_ms
|
|
45
|
+
history.reset_window
|
|
46
|
+
return [true, true]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# we have to take a baseline of this request/ response combo. we only
|
|
50
|
+
# baseline the first response, but we'll do full request analysis up
|
|
51
|
+
# to the baseline amount
|
|
52
|
+
return [true, history.window_hit == 1] if history.window_hit < @baseline
|
|
53
|
+
|
|
54
|
+
# Once the window_hit exceeds the baseline, we limit the analysis
|
|
55
|
+
# based on @request_frequency and @response_frequency.
|
|
56
|
+
non_baseline = history.window_hit - @baseline
|
|
57
|
+
analyze_request = (non_baseline % @request_frequency).zero?
|
|
58
|
+
analyze_response = (non_baseline % @response_frequency).zero?
|
|
59
|
+
|
|
60
|
+
[analyze_request, analyze_response]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
# RequestHistory tracks one requests history per time window
|
|
66
|
+
class RequestHistory
|
|
67
|
+
attr_accessor :window_start, :total_hit, :window_hit
|
|
68
|
+
|
|
69
|
+
def initialize
|
|
70
|
+
@window_start = Contrast::Utils::Timer.now_ms
|
|
71
|
+
@total_hit = 0
|
|
72
|
+
@window_hit = 0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def elapsed
|
|
76
|
+
Contrast::Utils::Timer.now_ms - @window_start
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def hit cnt = 1
|
|
80
|
+
@total_hit += cnt
|
|
81
|
+
@window_hit += cnt
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def reset_window
|
|
85
|
+
@window_start = Contrast::Utils::Timer.now_ms
|
|
86
|
+
@window_hit = 0
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def request_history request
|
|
91
|
+
@requests[request.hash_id] ||= RequestHistory.new
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
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/core_extensions/object'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Utils
|
|
8
|
+
module Assess
|
|
9
|
+
# TrackingUtil has methods for determining if a object is being tracked
|
|
10
|
+
class TrackingUtil
|
|
11
|
+
def self.tracked? obj
|
|
12
|
+
return false if obj.nil?
|
|
13
|
+
|
|
14
|
+
if Contrast::Utils::DuckUtils.quacks_like_tracked_hash?(obj)
|
|
15
|
+
obj.each_pair do |k, v|
|
|
16
|
+
return true if tracked?(k)
|
|
17
|
+
return true if tracked?(v)
|
|
18
|
+
end
|
|
19
|
+
false
|
|
20
|
+
elsif Contrast::Utils::DuckUtils.quacks_like_tracked_enumerable?(obj)
|
|
21
|
+
obj.any? do |ele|
|
|
22
|
+
tracked?(ele) unless obj == ele
|
|
23
|
+
end
|
|
24
|
+
elsif Contrast::Utils::DuckUtils.quacks_to?(obj, :cs__tracked?)
|
|
25
|
+
obj.cs__tracked?
|
|
26
|
+
else
|
|
27
|
+
false
|
|
28
|
+
end
|
|
29
|
+
rescue StandardError => e
|
|
30
|
+
# This is used to ask if a ton of objects are tracked. They may not
|
|
31
|
+
# all be iterable. Bad things could happen in some cases, like when
|
|
32
|
+
# checking a closed statement for SQL injection trigger events
|
|
33
|
+
logger.warn("#{ e } trying to TrackingUtil.tracked? on object of class #{ obj.cs__class }.")
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
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/object_share'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Utils
|
|
8
|
+
# Utility methods for asserting truthy or falsy state of a value expected
|
|
9
|
+
# to equate to a boolean
|
|
10
|
+
class BooleanUtil
|
|
11
|
+
class << self
|
|
12
|
+
# Ruby 2.4 does not nicely compare to nil, so we have to include
|
|
13
|
+
# these wrapper methods. RUBY-179 has the task to update this on
|
|
14
|
+
# EOL of 2.4 support
|
|
15
|
+
def false? config
|
|
16
|
+
return false unless config
|
|
17
|
+
return false if config == true
|
|
18
|
+
return true if config == false
|
|
19
|
+
|
|
20
|
+
Contrast::Utils::ObjectShare::FALSE.casecmp?(config)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def true? config
|
|
24
|
+
return false unless config
|
|
25
|
+
return false if config == false
|
|
26
|
+
return true if config == true
|
|
27
|
+
|
|
28
|
+
Contrast::Utils::ObjectShare::TRUE.casecmp?(config)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
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 Utils
|
|
6
|
+
# Implementation taken from http://stackoverflow.com/questions/1933866/efficient-ruby-lru-cache
|
|
7
|
+
class Cache
|
|
8
|
+
def initialize max_size = 1000
|
|
9
|
+
@max_size = max_size
|
|
10
|
+
@data = {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def max_size= size
|
|
14
|
+
return if size < 1
|
|
15
|
+
|
|
16
|
+
@max_size = size
|
|
17
|
+
return if @max_size >= @data.length
|
|
18
|
+
|
|
19
|
+
@data.keys[0..(@max_size - @data.length)].each do |k|
|
|
20
|
+
@data.delete(k)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def [] key
|
|
25
|
+
found = true
|
|
26
|
+
value = @data.delete(key) { found = false }
|
|
27
|
+
@data[key] = value if found
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def []= key, value
|
|
31
|
+
@data.delete(key)
|
|
32
|
+
@data[key] = value
|
|
33
|
+
@data.delete(@data.first[0]) if @data.length > @max_size
|
|
34
|
+
|
|
35
|
+
value # rubocop:disable Lint/Void
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def each
|
|
39
|
+
@data.reverse_each do |pair|
|
|
40
|
+
yield pair
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# used further up the chain, non thread safe each
|
|
45
|
+
alias_method :each_unsafe, :each
|
|
46
|
+
|
|
47
|
+
def to_a
|
|
48
|
+
@data.to_a.reverse
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def delete key
|
|
52
|
+
@data.delete(key)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def clear
|
|
56
|
+
@data.clear
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def count
|
|
60
|
+
@data.count
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# for cache validation only, ensures all is sound
|
|
64
|
+
def valid?
|
|
65
|
+
true
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
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/core_extensions/object'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Utils
|
|
8
|
+
# Utility methods for exploring the complete space of objects
|
|
9
|
+
class ClassUtil
|
|
10
|
+
def self.ancestors_of clazz
|
|
11
|
+
arr = []
|
|
12
|
+
ObjectSpace.each_object(Module) do |obj|
|
|
13
|
+
next unless obj <= clazz
|
|
14
|
+
|
|
15
|
+
arr << obj
|
|
16
|
+
end
|
|
17
|
+
arr
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# some classes have had things prepended to them, like Marshal in Rails
|
|
21
|
+
# 5 and higher. Their ActiveSupport::MarshalWithAutoloading will break
|
|
22
|
+
# our alias patching approach, as will any other prepend on something
|
|
23
|
+
# that we touch. Prepend and Alias are inherently incompatible monkey
|
|
24
|
+
# patching approaches. As such, we need to know if something has been
|
|
25
|
+
# prepended to.
|
|
26
|
+
#
|
|
27
|
+
# return true if the given module is not its first ancestor
|
|
28
|
+
def self.prepended? mod, ancestors = nil
|
|
29
|
+
ancestors ||= mod.ancestors
|
|
30
|
+
ancestors[0] != mod
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.determine_target_class mod, is_instance
|
|
34
|
+
return mod if mod.singleton_class?
|
|
35
|
+
|
|
36
|
+
return mod.cs__singleton_class unless is_instance
|
|
37
|
+
|
|
38
|
+
mod
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# return true if the given method is overwritten by one of the ancestors
|
|
42
|
+
# in the ancestor change that comes before the given module
|
|
43
|
+
def self.prepended_method? mod, method_policy
|
|
44
|
+
target_module = determine_target_class mod, method_policy.instance_method
|
|
45
|
+
ancestors = target_module.ancestors
|
|
46
|
+
return false unless prepended?(target_module, ancestors)
|
|
47
|
+
|
|
48
|
+
ancestors.each do |ancestor|
|
|
49
|
+
break if ancestor == target_module
|
|
50
|
+
|
|
51
|
+
methods = ancestor.instance_methods(false)
|
|
52
|
+
return true if methods.include?(method_policy.method_name)
|
|
53
|
+
end
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
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 Utils
|
|
6
|
+
# Stores the range of a comment
|
|
7
|
+
class CommentRange
|
|
8
|
+
COMMENT_START = /<!--/.cs__freeze
|
|
9
|
+
COMMENT_END = '-->'
|
|
10
|
+
|
|
11
|
+
attr_reader :open, :close
|
|
12
|
+
|
|
13
|
+
def initialize open_idx, close_idx
|
|
14
|
+
@open = open_idx
|
|
15
|
+
@close = close_idx
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
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 Utils
|
|
6
|
+
# Utility class used to determine information about the current data store
|
|
7
|
+
# on which a query was executed or to which the application is connected.
|
|
8
|
+
module DataStoreUtil
|
|
9
|
+
def self.report_data_store data_store
|
|
10
|
+
return unless data_store
|
|
11
|
+
|
|
12
|
+
context = Contrast::Agent::REQUEST_TRACKER.current
|
|
13
|
+
return unless context&.activity
|
|
14
|
+
|
|
15
|
+
context.activity.technologies[data_store] = true
|
|
16
|
+
context.activity.query_count += 1
|
|
17
|
+
return unless context.activity.query_count == 1
|
|
18
|
+
|
|
19
|
+
Contrast::Utils::InventoryUtil.append_db_config(context.activity)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
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 Utils
|
|
6
|
+
# Utility methods for identifying instances that can be used interchangably
|
|
7
|
+
class DuckUtils
|
|
8
|
+
def self.quacks_like_tracked_hash? obj
|
|
9
|
+
return false unless obj
|
|
10
|
+
return false if quacks_like_cs_patched?(obj)
|
|
11
|
+
|
|
12
|
+
obj.is_a?(Hash)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.quacks_like_tracked_enumerable? obj
|
|
16
|
+
return false unless obj
|
|
17
|
+
return false if obj.is_a?(IO)
|
|
18
|
+
# TODO: RUBY-606: temporary work around to avoid the agent treating OpenSSL::Buffering as a source,
|
|
19
|
+
# see https://contrast.atlassian.net/browse/RUBY-588
|
|
20
|
+
return false if defined?(OpenSSL::Buffering) && obj.is_a?(OpenSSL::Buffering)
|
|
21
|
+
return false if quacks_like_cs_patched?(obj)
|
|
22
|
+
|
|
23
|
+
obj.is_a?(Enumerable)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# This method will return true if the object being checked has been patched
|
|
27
|
+
# to have the cs__properties field. We check the cs__tracked? method since it
|
|
28
|
+
# is side effect free (ie doesn't cause the properties object to be created).
|
|
29
|
+
def self.quacks_like_cs_patched? obj
|
|
30
|
+
obj && quacks_to?(obj, :cs__tracked?)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# All Objects respond to dup. Not all Objects respond nicely. Nil, True,
|
|
34
|
+
# False and Number types respond with TypeError. This check should handle
|
|
35
|
+
# those cases.
|
|
36
|
+
# https://stackoverflow.com/questions/20954789/how-do-i-check-if-a-variable-really-responds-to-dup
|
|
37
|
+
def self.quacks_like_duplicable? obj
|
|
38
|
+
obj.cs__class.methods.include? :new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Most things that are closable IO's will in fact be of the IO type. That
|
|
42
|
+
# being said, some will also be extensions of DelegateClass with IO type,
|
|
43
|
+
# like Tempfile. We need to handle both cases.
|
|
44
|
+
def self.quacks_like_closable_io object
|
|
45
|
+
return false unless Contrast::Utils::IOUtil.io?(object)
|
|
46
|
+
|
|
47
|
+
quacks_to?(object, :closed?)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.quacks_to? object, method
|
|
51
|
+
return true if object.cs__respond_to?(method)
|
|
52
|
+
return false unless object.is_a?(Delegator)
|
|
53
|
+
|
|
54
|
+
object.cs__delegator_respond_to?(method)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
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 Utils
|
|
6
|
+
# Stores key and value of a environmnt variable and can normalize the
|
|
7
|
+
# path for comparison to common config
|
|
8
|
+
class EnvConfigurationItem
|
|
9
|
+
START_UNDERSCORE = /^(_+)/.cs__freeze
|
|
10
|
+
END_UNDERSCORE = /(_+)$/.cs__freeze
|
|
11
|
+
REPEATING_UNDERSCORE = /_{3,}/.cs__freeze
|
|
12
|
+
|
|
13
|
+
attr_reader :value, :dot_path_array
|
|
14
|
+
|
|
15
|
+
def initialize key, value
|
|
16
|
+
key = EnvConfigurationItem.resolve_corrected_path(key)
|
|
17
|
+
@dot_path_array = key.downcase.split(Contrast::Utils::ObjectShare::DOUBLE_UNDERSCORE)
|
|
18
|
+
@value = value
|
|
19
|
+
|
|
20
|
+
correct_dot_path
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def correct_dot_path
|
|
24
|
+
return unless @dot_path_array
|
|
25
|
+
|
|
26
|
+
# we need to shift by one to access the appropriate level of the config
|
|
27
|
+
@dot_path_array.shift
|
|
28
|
+
# and then we need to fix any rules
|
|
29
|
+
idx = @dot_path_array.find_index('rules')
|
|
30
|
+
return unless idx
|
|
31
|
+
|
|
32
|
+
next_idx = idx + 1
|
|
33
|
+
return if next_idx == @dot_path_array.length
|
|
34
|
+
|
|
35
|
+
@dot_path_array[next_idx] = @dot_path_array[next_idx].to_s.tr('_', '-')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.resolve_corrected_path path
|
|
39
|
+
tmp_path = path.dup
|
|
40
|
+
start_match = START_UNDERSCORE.match(tmp_path)
|
|
41
|
+
tmp_path = tmp_path[start_match.offset(0).last..-1] if start_match
|
|
42
|
+
|
|
43
|
+
tmp_path.gsub!(REPEATING_UNDERSCORE, '__')
|
|
44
|
+
|
|
45
|
+
end_match = END_UNDERSCORE.match(tmp_path)
|
|
46
|
+
tmp_path = tmp_path[0...end_match.offset(0).first] if end_match
|
|
47
|
+
|
|
48
|
+
tmp_path
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|