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,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 'objspace'
|
|
5
|
+
cs__scoped_require 'contrast/components/interface'
|
|
6
|
+
|
|
7
|
+
module Contrast
|
|
8
|
+
module Utils
|
|
9
|
+
# Implementation of a heap dump util to automate generation
|
|
10
|
+
class HeapDumpUtil
|
|
11
|
+
include Contrast::Components::Interface
|
|
12
|
+
access_component :logging, :heap_dump
|
|
13
|
+
|
|
14
|
+
LOG_ERROR_DUMPS = 'Unable to generate heap dumps'
|
|
15
|
+
FILE_WRITE_FLAGS = 'w'
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
def run
|
|
19
|
+
return unless heap_dump_enabled?
|
|
20
|
+
|
|
21
|
+
log_enabled_warning
|
|
22
|
+
dir = heap_dump_control[:path]
|
|
23
|
+
Dir.mkdir(dir) unless Dir.exist?(dir)
|
|
24
|
+
return unless File.writable?(dir)
|
|
25
|
+
|
|
26
|
+
delay = heap_dump_control[:delay]
|
|
27
|
+
Contrast::Agent::Thread.new do
|
|
28
|
+
logger.info("HEAP DUMP THREAD INITIALIZED. WAITING #{ delay } SECONDS TO BEGIN.")
|
|
29
|
+
sleep(delay)
|
|
30
|
+
capture_heap_dump
|
|
31
|
+
end
|
|
32
|
+
rescue StandardError => e
|
|
33
|
+
logger.info(LOG_ERROR_DUMPS, e)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def log_enabled_warning
|
|
37
|
+
dir = heap_dump_control[:path]
|
|
38
|
+
window = heap_dump_control[:window]
|
|
39
|
+
count = heap_dump_control[:count]
|
|
40
|
+
delay = heap_dump_control[:delay]
|
|
41
|
+
clean = heap_dump_control[:clean]
|
|
42
|
+
|
|
43
|
+
logger.info <<~WARNING
|
|
44
|
+
*****************************************************
|
|
45
|
+
******** HEAP DUMP HAS BEEN ENABLED ********
|
|
46
|
+
*** APPLICATION PROCESS WILL EXIT UPON COMPLETION ***
|
|
47
|
+
*****************************************************
|
|
48
|
+
|
|
49
|
+
Heap dump is a debugging tool that snapshots the entire
|
|
50
|
+
state of the Ruby VM. It is an exceptionally expensive
|
|
51
|
+
process, and should only be used to debug especially
|
|
52
|
+
pernicious errors.
|
|
53
|
+
|
|
54
|
+
It will write multiple memory snaphots, which are liable
|
|
55
|
+
to be multiple gigabytes in size.
|
|
56
|
+
They will be named "[unix timestamp]-heap.dump",
|
|
57
|
+
e.g.: 1020304050-heap.dump
|
|
58
|
+
|
|
59
|
+
It will then call Ruby `exit()`.
|
|
60
|
+
|
|
61
|
+
If this is not your specific intent, you can (and should)
|
|
62
|
+
disable this option in your Contrast config file.
|
|
63
|
+
|
|
64
|
+
HEAP DUMP PARAMETERS:
|
|
65
|
+
\t[write files to this directory] dir: #{ dir }
|
|
66
|
+
\t[wait this many seconds in between dumps] window: #{ window }
|
|
67
|
+
\t[heap dump this many times] count: #{ count }
|
|
68
|
+
\t[wait this many seconds into app lifetime] delay: #{ delay }
|
|
69
|
+
\t[perform gc pass before dump] clean: #{ clean }
|
|
70
|
+
|
|
71
|
+
*****************************************************
|
|
72
|
+
******** YOU HAVE BEEN WARNED ********
|
|
73
|
+
*****************************************************
|
|
74
|
+
WARNING
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def capture_heap_dump
|
|
78
|
+
dir = heap_dump_control[:path]
|
|
79
|
+
window = heap_dump_control[:window]
|
|
80
|
+
count = heap_dump_control[:count]
|
|
81
|
+
clean = heap_dump_control[:clean]
|
|
82
|
+
logger.info(nil, 'HEAP DUMP MAIN LOOP')
|
|
83
|
+
ObjectSpace.trace_object_allocations_start
|
|
84
|
+
count.times do |i|
|
|
85
|
+
logger.info(nil, "STARTING HEAP DUMP PASS #{ i + 1 } OF #{ count }")
|
|
86
|
+
output = "#{ Time.now.to_f }-heap.dump"
|
|
87
|
+
output = File.join(dir, output)
|
|
88
|
+
begin
|
|
89
|
+
logger.info(nil, "OPENING FILE #{ dir }/#{ output } FOR HEAP DUMP")
|
|
90
|
+
file = File.new(output, FILE_WRITE_FLAGS)
|
|
91
|
+
if clean
|
|
92
|
+
logger.info(nil, 'PERFORMING GARBAGE COLLECTION BEFORE HEAP DUMP')
|
|
93
|
+
GC.start
|
|
94
|
+
end
|
|
95
|
+
ObjectSpace.dump_all(output: file)
|
|
96
|
+
logger.info(nil, "FINISHING HEAP DUMP PASS #{ i + 1 } OF #{ count }")
|
|
97
|
+
ensure
|
|
98
|
+
file.close
|
|
99
|
+
end
|
|
100
|
+
sleep(window)
|
|
101
|
+
end
|
|
102
|
+
ensure
|
|
103
|
+
ObjectSpace.trace_object_allocations_stop
|
|
104
|
+
logger.info(nil, '*****************************************************')
|
|
105
|
+
logger.info(nil, '******** HEAP DUMP HAS CONCLUDED ********')
|
|
106
|
+
logger.info(nil, '*** APPLICATION PROCESS WILL EXIT SHORTLY ***')
|
|
107
|
+
logger.info(nil, '*****************************************************')
|
|
108
|
+
exit # We weren't kidding!
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
+
# frozen_string_literal: false
|
|
3
|
+
|
|
4
|
+
cs__scoped_require 'contrast/components/interface'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Utils
|
|
8
|
+
# This utility allows us to report invalid configurations detected in
|
|
9
|
+
# customer applications, as determined by Configuration Rules at runtime.
|
|
10
|
+
module InvalidConfigurationUtil
|
|
11
|
+
include Contrast::Components::Interface
|
|
12
|
+
access_component :agent, :analysis, :contrast_service, :logging
|
|
13
|
+
|
|
14
|
+
CS__PATH = 'path'.cs__freeze
|
|
15
|
+
CS__SESSION_ID = 'sessionId'.cs__freeze
|
|
16
|
+
CS__SNIPPET = 'snippet'.cs__freeze
|
|
17
|
+
|
|
18
|
+
# Build and report a finding for the given rule
|
|
19
|
+
#
|
|
20
|
+
# @param rule_id [String] the rule that was violated by the configuration
|
|
21
|
+
# @param user_provided_options [Hash] the configuration value(s) which
|
|
22
|
+
# violated the rule
|
|
23
|
+
# @param call_location [Thread::Backtrace::Location] the location where
|
|
24
|
+
# the bad configuration was set
|
|
25
|
+
def cs__report_finding rule_id, user_provided_options, call_location
|
|
26
|
+
finding = Contrast::Api::Dtm::Finding.new
|
|
27
|
+
finding.rule_id = rule_id
|
|
28
|
+
path = call_location.path
|
|
29
|
+
# just get the file name, not the full path
|
|
30
|
+
path = path.split(Contrast::Utils::ObjectShare::SLASH).last
|
|
31
|
+
session_id = user_provided_options[:key].to_s if user_provided_options
|
|
32
|
+
|
|
33
|
+
finding.version = Contrast::Agent::Assess::Policy::TriggerMethod::CURRENT_FINDING_VERSION
|
|
34
|
+
finding.properties[CS__SESSION_ID] = Contrast::Utils::StringUtils.force_utf8(session_id)
|
|
35
|
+
finding.properties[CS__PATH] = Contrast::Utils::StringUtils.force_utf8(path)
|
|
36
|
+
file_path = call_location.absolute_path
|
|
37
|
+
snippet = file_snippet(file_path, call_location)
|
|
38
|
+
finding.properties[CS__SNIPPET] = Contrast::Utils::StringUtils.force_utf8(snippet)
|
|
39
|
+
|
|
40
|
+
hash = Contrast::Utils::HashDigest.generate_config_hash(finding)
|
|
41
|
+
finding.hash_code = Contrast::Utils::StringUtils.force_utf8(hash)
|
|
42
|
+
finding.preflight = Contrast::Utils::PreflightUtil.create_preflight(finding)
|
|
43
|
+
|
|
44
|
+
activity = Contrast::Api::Dtm::Activity.new
|
|
45
|
+
activity.findings << finding
|
|
46
|
+
|
|
47
|
+
# If assess is enabled, we can just send the activity
|
|
48
|
+
if ASSESS.enabled?
|
|
49
|
+
build_tags(activity)
|
|
50
|
+
CONTRAST_SERVICE.queue_message activity
|
|
51
|
+
# Otherwise, if the Agent isn't ready, we have to queue the messages
|
|
52
|
+
# until we know the starting state.
|
|
53
|
+
else
|
|
54
|
+
Contrast::Utils::ServiceSenderUtil.add_to_assess_messages activity
|
|
55
|
+
end
|
|
56
|
+
rescue StandardError => e
|
|
57
|
+
logger.error(e, "Unable to build a finding for #{ rule_id }")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# This seems silly to pull out, but we can ONLY call this in the case
|
|
63
|
+
# where we have a configuration. Doing otherwise results in a bad error
|
|
64
|
+
# case where we try to do other things, like logging, which behave
|
|
65
|
+
# strangely without a config
|
|
66
|
+
def build_tags activity
|
|
67
|
+
activity.finding_tags = Contrast::Utils::StringUtils.force_utf8(ASSESS.tags)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def file_snippet file_path, call_location
|
|
71
|
+
idx = call_location&.lineno
|
|
72
|
+
if file_path && idx && File.exist?(file_path)
|
|
73
|
+
idx = idx > 5 ? idx - 5 : 0
|
|
74
|
+
snippet = ''
|
|
75
|
+
File.foreach(file_path).with_index do |line, line_num|
|
|
76
|
+
next unless line_num >= idx
|
|
77
|
+
break if line_num > idx + 10
|
|
78
|
+
|
|
79
|
+
snippet << line
|
|
80
|
+
snippet << Contrast::Utils::ObjectShare::NEW_LINE
|
|
81
|
+
end
|
|
82
|
+
return snippet
|
|
83
|
+
end
|
|
84
|
+
call_location&.label&.dup
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
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/timer'
|
|
5
|
+
cs__scoped_require 'contrast/utils/object_share'
|
|
6
|
+
cs__scoped_require 'contrast/utils/gemfile_reader'
|
|
7
|
+
cs__scoped_require 'contrast/components/interface'
|
|
8
|
+
|
|
9
|
+
module Contrast
|
|
10
|
+
module Utils
|
|
11
|
+
# Utilities for getting inventory information from the application
|
|
12
|
+
class InventoryUtil
|
|
13
|
+
include Contrast::Components::Interface
|
|
14
|
+
access_component :logging
|
|
15
|
+
|
|
16
|
+
# TeamServer only accepts certain values for ArchitectureComponents.
|
|
17
|
+
# DO NOT CHANGE THIS!
|
|
18
|
+
AC_TYPE_DB = 'db'
|
|
19
|
+
# TeamServer only accepts certain values for FlowMap Services.
|
|
20
|
+
# DO NOT CHANGE THIS
|
|
21
|
+
DATABASE = 'Database'
|
|
22
|
+
ADAPTER = 'adapter'
|
|
23
|
+
HOST = 'host'
|
|
24
|
+
PORT = 'port'
|
|
25
|
+
DATABASE_LOWER = 'database'
|
|
26
|
+
DEFAULT = 'default'
|
|
27
|
+
LOCALHOST = 'localhost'
|
|
28
|
+
|
|
29
|
+
def self.inventory_class class_path
|
|
30
|
+
Contrast::Utils::GemfileReader.instance.map_class(class_path)
|
|
31
|
+
rescue StandardError => e
|
|
32
|
+
logger.error(e, "Unable to inventory #{ class_path }")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.active_record_config
|
|
36
|
+
return @_active_record_config if instance_variable_defined?(:@_active_record_config)
|
|
37
|
+
|
|
38
|
+
@_active_record_config = ActiveRecord::Base.connection_config rescue nil # rubocop:disable Style/RescueModifier
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.append_db_config activity_or_update, hash_or_str = Contrast::Utils::InventoryUtil.active_record_config
|
|
42
|
+
arr = build_from_db_config(hash_or_str)
|
|
43
|
+
return unless arr&.any?
|
|
44
|
+
|
|
45
|
+
activity_or_update.technologies[DATABASE] = true
|
|
46
|
+
arr.each do |a|
|
|
47
|
+
next unless a
|
|
48
|
+
|
|
49
|
+
if activity_or_update.is_a?(Contrast::Api::Dtm::Activity)
|
|
50
|
+
activity_or_update.architectures << a
|
|
51
|
+
else
|
|
52
|
+
activity_or_update.components << a
|
|
53
|
+
end
|
|
54
|
+
next if a.vendor.empty?
|
|
55
|
+
|
|
56
|
+
activity_or_update.technologies[a.vendor] = true
|
|
57
|
+
end
|
|
58
|
+
rescue StandardError => e
|
|
59
|
+
logger.error(e, 'Unable to append db config')
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.build_from_db_config hash_or_str
|
|
64
|
+
return unless hash_or_str
|
|
65
|
+
|
|
66
|
+
if hash_or_str.is_a?(Hash)
|
|
67
|
+
build_from_db_hash(hash_or_str)
|
|
68
|
+
else
|
|
69
|
+
build_from_db_string(hash_or_str.to_s)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.build_from_db_hash hash
|
|
74
|
+
ac = Contrast::Api::Dtm::ArchitectureComponent.new
|
|
75
|
+
ac.vendor = hash[:adapter] || hash[ADAPTER] || Contrast::Utils::ObjectShare::EMPTY_STRING
|
|
76
|
+
ac.remote_host = host_from_hash(hash)
|
|
77
|
+
ac.remote_port = port_from_hash(hash)
|
|
78
|
+
ac.type = AC_TYPE_DB
|
|
79
|
+
ac.url = hash[:database] || hash[DATABASE_LOWER] || DEFAULT
|
|
80
|
+
[ac]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.host_from_hash hash
|
|
84
|
+
hash[:host] || hash[HOST] || Contrast::Utils::ObjectShare::EMPTY_STRING
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def self.port_from_hash hash
|
|
88
|
+
p = hash[:port] || hash[PORT] || Contrast::Utils::ObjectShare::EMPTY_STRING
|
|
89
|
+
p.to_i
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Examples:
|
|
93
|
+
# mongodb://[user:pass@]host1[:port1][,host2[:port2],[,hostN[:portN]]][/[database][?options]]
|
|
94
|
+
# postgresql://scott:tiger@localhost/mydatabase
|
|
95
|
+
# mysql+mysqlconnector://scott:tiger@localhost/foo
|
|
96
|
+
def self.build_from_db_string str
|
|
97
|
+
adapter, hosts, database = split_connection_str(str)
|
|
98
|
+
acs = []
|
|
99
|
+
hosts.split(Contrast::Utils::ObjectShare::COMMA).map do |s|
|
|
100
|
+
host, port = s.split(Contrast::Utils::ObjectShare::COLON)
|
|
101
|
+
|
|
102
|
+
ac = Contrast::Api::Dtm::ArchitectureComponent.new
|
|
103
|
+
ac.vendor = Contrast::Utils::StringUtils.force_utf8(adapter)
|
|
104
|
+
ac.remote_host = Contrast::Utils::StringUtils.force_utf8(host)
|
|
105
|
+
ac.remote_port = port.to_i
|
|
106
|
+
ac.type = AC_TYPE_DB
|
|
107
|
+
ac.url = Contrast::Utils::StringUtils.force_utf8(database)
|
|
108
|
+
acs << ac
|
|
109
|
+
end
|
|
110
|
+
acs
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.split_connection_str str
|
|
114
|
+
adapter, str = str.split(Contrast::Utils::ObjectShare::COLON_SLASH_SLASH)
|
|
115
|
+
_auth, str = str.split(Contrast::Utils::ObjectShare::AT)
|
|
116
|
+
# Not currently used
|
|
117
|
+
# user, pass = auth.split(Contrast::Utils::ObjectShare::COLON)
|
|
118
|
+
hosts, db_and_options = str.split(Contrast::Utils::ObjectShare::SLASH)
|
|
119
|
+
hosts << LOCALHOST if hosts.empty?
|
|
120
|
+
database, _options = db_and_options.split(Contrast::Utils::ObjectShare::QUESTION_MARK)
|
|
121
|
+
|
|
122
|
+
[adapter, hosts, database]
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
cs__scoped_require 'contrast/components/interface'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Utils
|
|
8
|
+
# Util for information about an IO
|
|
9
|
+
class IOUtil
|
|
10
|
+
include Contrast::Components::Interface
|
|
11
|
+
|
|
12
|
+
access_component :logging
|
|
13
|
+
|
|
14
|
+
# StringIO is a valid path because it logs directly to a string buffer
|
|
15
|
+
def self.write_permission? path
|
|
16
|
+
return false if path.nil?
|
|
17
|
+
return true if path.is_a?(StringIO)
|
|
18
|
+
return File.writable?(path) if File.exist?(path)
|
|
19
|
+
|
|
20
|
+
dir_name = File.dirname(File.absolute_path(path))
|
|
21
|
+
File.writable?(dir_name)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# We're only going to call rewind on things that we believe are safe to
|
|
25
|
+
# call it on. This method white lists those cases and returns false in
|
|
26
|
+
# all others.
|
|
27
|
+
def self.should_rewind? potential_io
|
|
28
|
+
return true if potential_io.is_a?(StringIO)
|
|
29
|
+
return false unless io?(potential_io)
|
|
30
|
+
|
|
31
|
+
should_rewind_io?(potential_io)
|
|
32
|
+
rescue StandardError => e
|
|
33
|
+
logger.debug(e, "Encountered an issue inspecting instance of #{ potential_io } - continuing without rewind")
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# IO cannot be used with streams such as pipes, ttys, and sockets.
|
|
38
|
+
def self.should_rewind_io? io
|
|
39
|
+
return false if io.tty?
|
|
40
|
+
|
|
41
|
+
status = io.stat
|
|
42
|
+
return false unless status
|
|
43
|
+
return false if status.pipe?
|
|
44
|
+
return false if status.socket?
|
|
45
|
+
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# A class is IO if it is a decedent or delegate of IO
|
|
50
|
+
def self.io? object
|
|
51
|
+
return true if object.is_a?(IO)
|
|
52
|
+
|
|
53
|
+
# DelegateClass, which is a Delegator, defines __getobj__ as a way to
|
|
54
|
+
# get the object that the class wraps around (delegates to)
|
|
55
|
+
return false unless object.is_a?(Delegator)
|
|
56
|
+
|
|
57
|
+
object.__getobj__.is_a?(IO)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
# rubocop:disable Object/Freeze
|
|
5
|
+
module Contrast
|
|
6
|
+
module Utils
|
|
7
|
+
# A utility class where a series of commonly used Strings and other
|
|
8
|
+
# commonly used objects can be store and frozen to prevent unnecessary
|
|
9
|
+
# duplication.
|
|
10
|
+
class ObjectShare
|
|
11
|
+
# Strings
|
|
12
|
+
AND = '&'
|
|
13
|
+
OR = '||'
|
|
14
|
+
PIPE = '|'
|
|
15
|
+
ASTERISK = '*'
|
|
16
|
+
BACK_SLASH = '\\'
|
|
17
|
+
EMPTY_STRING = ''
|
|
18
|
+
COLON = ':'
|
|
19
|
+
COMMA = ','
|
|
20
|
+
DASH = '-'
|
|
21
|
+
DOUBLE_QUOTE = '"'
|
|
22
|
+
EQUALS = '='
|
|
23
|
+
EXCLAMATION = '!'
|
|
24
|
+
HTTP_SCORE = 'HTTP_'
|
|
25
|
+
HTTP_START = 'http:'
|
|
26
|
+
HTTPS_START = 'https:'
|
|
27
|
+
NEW_LINE = "\n"
|
|
28
|
+
NIL_STRING = 'nil'
|
|
29
|
+
PERIOD = '.'
|
|
30
|
+
PLUS_SIGN = '+'
|
|
31
|
+
POUND_SIGN = HASH_CHAR = '#'
|
|
32
|
+
QUESTION_MARK = '?'
|
|
33
|
+
RETURN = "\r"
|
|
34
|
+
SEMICOLON = ';'
|
|
35
|
+
SINGLE_QUOTE = '\''
|
|
36
|
+
SLASH = '/'
|
|
37
|
+
SPACE = ' '
|
|
38
|
+
UNDERSCORE = '_'
|
|
39
|
+
DOUBLE_UNDERSCORE = '__'
|
|
40
|
+
AT = '@'
|
|
41
|
+
LEFT_ANGLE = '<'
|
|
42
|
+
RIGHT_ANGLE = '>'
|
|
43
|
+
LEFT_BRACKET = '['
|
|
44
|
+
RIGHT_BRACKET = ']'
|
|
45
|
+
LEFT_PAREN = '('
|
|
46
|
+
RIGHT_PAREN = ')'
|
|
47
|
+
COLON_SLASH_SLASH = '://'
|
|
48
|
+
TICK = '`'
|
|
49
|
+
BACK_TICK = '`'
|
|
50
|
+
LEFT_CURLY = '{'
|
|
51
|
+
RIGHT_CURLY = '}'
|
|
52
|
+
DOLLAR_SIGN = '$'
|
|
53
|
+
CARROT = '^'
|
|
54
|
+
PERCENT = '%'
|
|
55
|
+
LETTER_Q = 'Q'
|
|
56
|
+
OR_STRING = 'or'
|
|
57
|
+
|
|
58
|
+
DOUBLE_QUOTE_ESCAPED = '"'
|
|
59
|
+
|
|
60
|
+
READ_FLAG = 'r'
|
|
61
|
+
WRITE_FLAG = 'w'
|
|
62
|
+
READ_WRITE_FLAG = 'rw'
|
|
63
|
+
|
|
64
|
+
PARENT_PATH = '..'
|
|
65
|
+
|
|
66
|
+
RUBY = 'Ruby'
|
|
67
|
+
CACHE = 'cache'
|
|
68
|
+
GEM_SUFFIX = '.gem'
|
|
69
|
+
|
|
70
|
+
CONTRAST_METHOD_START = 'cs__'
|
|
71
|
+
CONTRAST_PATCHED_METHOD_START = 'cs__patched_'
|
|
72
|
+
CONTRAST_MODULE_START = 'Contrast::'
|
|
73
|
+
ANONYMOUS_CLASS_MARKER = '#<'
|
|
74
|
+
DOUBLE_COLON = '::'
|
|
75
|
+
|
|
76
|
+
EMPTY_ARRAY = [].freeze
|
|
77
|
+
EMPTY_HASH = {}.freeze
|
|
78
|
+
EMPTY_TRIPLE = [EMPTY_STRING, EMPTY_STRING, EMPTY_STRING].freeze
|
|
79
|
+
|
|
80
|
+
# RegExps
|
|
81
|
+
DIGIT_REGEXP = /[[:digit:]]/.freeze
|
|
82
|
+
WHITE_SPACE_REGEXP = /\s/.freeze
|
|
83
|
+
NOT_WHITE_SPACE_REGEXP = /[^\s]/.freeze
|
|
84
|
+
WINDOWS_REGEXP = /cygwin|mswin|mingw|bccwin|wince|emx/.freeze
|
|
85
|
+
|
|
86
|
+
# Messages
|
|
87
|
+
OVERRIDE_MESSAGE = 'A security filter prevented original response from being returned.'
|
|
88
|
+
|
|
89
|
+
# Configs
|
|
90
|
+
TRUE = 'true'
|
|
91
|
+
FALSE = 'false'
|
|
92
|
+
|
|
93
|
+
CLASS = 'Class'
|
|
94
|
+
MODULE = 'Module'
|
|
95
|
+
|
|
96
|
+
BRACKET_INTERPOLATION_START = '#{'
|
|
97
|
+
|
|
98
|
+
OBJECT_KEY = 'O'
|
|
99
|
+
PARAMETER_KEY = 'P'
|
|
100
|
+
RETURN_KEY = 'R'
|
|
101
|
+
UNKNOWN = 'unknown'
|
|
102
|
+
|
|
103
|
+
INDEX = 'index'
|
|
104
|
+
|
|
105
|
+
VERSION_2_5_0 = '2.5.0'
|
|
106
|
+
VERSION_2_4_2 = '2.4.2'
|
|
107
|
+
VERSION_2_4_1 = '2.4.1'
|
|
108
|
+
VERSION_2_4_0 = '2.4.0'
|
|
109
|
+
VERSION_2_3_5 = '2.3.5'
|
|
110
|
+
VERSION_2_3_4 = '2.3.4'
|
|
111
|
+
VERSION_2_3_0 = '2.3.0'
|
|
112
|
+
VERSION_2_0_4 = '2.0.4'
|
|
113
|
+
VERSION_2_0_0 = '2.0.0'
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
# rubocop:enable Object/Freeze
|