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,22 @@
|
|
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 Config
|
6
|
+
# Common Configuration settings. Those in this section pertain to the
|
7
|
+
# sampling functionality of the Agent.
|
8
|
+
class SamplingConfiguration < BaseConfiguration
|
9
|
+
KEYS = {
|
10
|
+
enable: EMPTY_VALUE,
|
11
|
+
baseline: EMPTY_VALUE,
|
12
|
+
request_frequency: EMPTY_VALUE,
|
13
|
+
response_frequency: EMPTY_VALUE,
|
14
|
+
window_ms: EMPTY_VALUE
|
15
|
+
}.cs__freeze
|
16
|
+
|
17
|
+
def initialize hsh
|
18
|
+
super(hsh, KEYS)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
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 Config
|
6
|
+
# Common Configuration settings. Those in this section pertain to the
|
7
|
+
# server identification functionality of the Agent.
|
8
|
+
class ServerConfiguration < BaseConfiguration
|
9
|
+
KEYS = {
|
10
|
+
name: EMPTY_VALUE,
|
11
|
+
path: EMPTY_VALUE,
|
12
|
+
type: EMPTY_VALUE,
|
13
|
+
tags: EMPTY_VALUE,
|
14
|
+
environment: EMPTY_VALUE,
|
15
|
+
version: EMPTY_VALUE
|
16
|
+
}.cs__freeze
|
17
|
+
|
18
|
+
def initialize hsh
|
19
|
+
super(hsh, KEYS)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
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 Config
|
6
|
+
# Common Configuration settings. Those in this section pertain to the
|
7
|
+
# communication between the Agent & the Service.
|
8
|
+
class ServiceConfiguration < BaseConfiguration
|
9
|
+
KEYS = {
|
10
|
+
enable: EMPTY_VALUE,
|
11
|
+
host: EMPTY_VALUE,
|
12
|
+
port: EMPTY_VALUE,
|
13
|
+
socket: EMPTY_VALUE,
|
14
|
+
logger: Contrast::Config::LoggerConfiguration
|
15
|
+
}.cs__freeze
|
16
|
+
|
17
|
+
def initialize hsh
|
18
|
+
super(hsh, KEYS)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,214 @@
|
|
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 'yaml'
|
5
|
+
cs__scoped_require 'fileutils'
|
6
|
+
|
7
|
+
cs__scoped_require 'contrast/config'
|
8
|
+
cs__scoped_require 'contrast/utils/object_share'
|
9
|
+
cs__scoped_require 'contrast/components/interface'
|
10
|
+
|
11
|
+
module Contrast
|
12
|
+
# This is how we read in the local settings for the Agent, both ENV/ CMD line
|
13
|
+
# and from properties files, in order to determine which settings, if any,
|
14
|
+
# the user has overridden.
|
15
|
+
class Configuration
|
16
|
+
extend Forwardable
|
17
|
+
|
18
|
+
include Contrast::Components::Interface
|
19
|
+
|
20
|
+
access_component :scope
|
21
|
+
|
22
|
+
def_delegator :root, :assign_value_to_path_array
|
23
|
+
|
24
|
+
attr_reader :default_name, :root
|
25
|
+
|
26
|
+
DEFAULT_YAML_PATH = 'contrast_security.yaml'
|
27
|
+
DEFAULT_HOST = '127.0.0.1'
|
28
|
+
DEFAULT_PORT = '30555'
|
29
|
+
MILLISECOND_MARKER = '_ms'
|
30
|
+
CONVERSION = {
|
31
|
+
'agent.service.enable' => 'agent.start_bundled_service'
|
32
|
+
}.cs__freeze
|
33
|
+
CONFIG_BASE_PATHS = [
|
34
|
+
'',
|
35
|
+
'config/',
|
36
|
+
'/etc/contrast/ruby/',
|
37
|
+
'/etc/contrast/',
|
38
|
+
'/etc/'
|
39
|
+
].cs__freeze
|
40
|
+
REMOVE_FIELDS = [
|
41
|
+
'contrast'
|
42
|
+
].cs__freeze
|
43
|
+
|
44
|
+
def initialize cli_options = nil, default_name = DEFAULT_YAML_PATH
|
45
|
+
@default_name = default_name
|
46
|
+
|
47
|
+
# Load config_kv from file
|
48
|
+
config_kv = deep_stringify_all_keys(load_config)
|
49
|
+
|
50
|
+
# Overlay CLI options - they take precedence over config file
|
51
|
+
cli_options = deep_stringify_all_keys(cli_options)
|
52
|
+
config_kv = deep_merge(cli_options, config_kv) if cli_options
|
53
|
+
|
54
|
+
# Some in-flight rewrites to maintain backwards compatibility
|
55
|
+
config_kv = update_prop_keys(config_kv)
|
56
|
+
config_kv = deprecate_fields(config_kv)
|
57
|
+
|
58
|
+
@root = Contrast::Config::RootConfiguration.new(config_kv)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Because we call this method to determine the need for scoping, it itself
|
62
|
+
# must be executed inside a Contrast scope. Failure to do so could result
|
63
|
+
# in an infinite loop on the to_sym method used later.
|
64
|
+
def method_missing symbol, *args
|
65
|
+
with_contrast_scope do
|
66
|
+
begin
|
67
|
+
root.public_send(symbol, *args)
|
68
|
+
rescue NoMethodError => _e
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def respond_to_missing? method_name, *args
|
75
|
+
root&.cs__respond_to?(method_name) || super
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
# TODO: RUBY-546 move utility methods to auxiliary classes
|
81
|
+
|
82
|
+
def load_config
|
83
|
+
config = {}
|
84
|
+
configuration_paths.find do |path|
|
85
|
+
found = File.exist?(path)
|
86
|
+
next unless found
|
87
|
+
|
88
|
+
readable = File.readable?(path)
|
89
|
+
unless readable
|
90
|
+
puts "!!! Contrast - Configuration file at #{ path } is not readable by current user"
|
91
|
+
next
|
92
|
+
end
|
93
|
+
config = yaml_to_hash(path)
|
94
|
+
break
|
95
|
+
end
|
96
|
+
|
97
|
+
if config.empty?
|
98
|
+
puts "!!! Contrast - working directory: #{ Dir.pwd }"
|
99
|
+
puts '!!! Contrast - configuration file could not be found at any of the search paths'
|
100
|
+
puts 'Valid configuration paths are: '
|
101
|
+
configuration_paths.each do |path|
|
102
|
+
puts(path)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
config
|
106
|
+
end
|
107
|
+
|
108
|
+
def yaml_to_hash path
|
109
|
+
if path && File.readable?(path)
|
110
|
+
begin
|
111
|
+
yaml = IO.read(path)
|
112
|
+
yaml = ERB.new(yaml).result if defined?(ERB)
|
113
|
+
return YAML.safe_load(yaml)
|
114
|
+
rescue RuntimeError => e
|
115
|
+
puts "ERROR: unable to load configuration from path due to #{ e }"
|
116
|
+
puts "ERROR: path=#{ path } pwd=#{ Dir.pwd }"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
{}
|
121
|
+
end
|
122
|
+
|
123
|
+
# We're updating properties loaded from the configuration
|
124
|
+
# files to match the new agreed upon standard configuration
|
125
|
+
# names, so that one file works for all agents
|
126
|
+
def update_prop_keys config
|
127
|
+
converted = false
|
128
|
+
CONVERSION.each_pair do |old_method, new_method|
|
129
|
+
# See if the old value was set and needs to be translated
|
130
|
+
deprecated_keys = old_method.split('.')
|
131
|
+
|
132
|
+
old_value = config
|
133
|
+
deprecated_keys.each do |key|
|
134
|
+
old_value = old_value[key]
|
135
|
+
break if old_value.nil?
|
136
|
+
end
|
137
|
+
|
138
|
+
next if old_value.nil?
|
139
|
+
|
140
|
+
converted = true
|
141
|
+
|
142
|
+
puts "The deprecated property #{ old_method } is being set."
|
143
|
+
puts "Please update your config to use the property #{ new_method } instead."
|
144
|
+
|
145
|
+
new_keys = new_method.split('.')
|
146
|
+
|
147
|
+
# We changed the seconds values into ms values. Multiply them accordingly
|
148
|
+
old_value = old_value.to_i * 1000 if new_method.end_with?(MILLISECOND_MARKER)
|
149
|
+
|
150
|
+
new_value = config
|
151
|
+
end_idx = new_keys.length - 1
|
152
|
+
new_keys.each_with_index do |new_key, index|
|
153
|
+
if index == end_idx
|
154
|
+
new_value[new_key] = old_value if new_value[new_key].nil?
|
155
|
+
else
|
156
|
+
new_value = {} if new_value.nil?
|
157
|
+
new_value[new_key] = {} if new_value[new_key].nil?
|
158
|
+
new_value = new_value[new_key]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
config
|
164
|
+
end
|
165
|
+
|
166
|
+
def deprecate_fields hash
|
167
|
+
REMOVE_FIELDS.each do |field|
|
168
|
+
path = field.split('.')
|
169
|
+
active_path = hash
|
170
|
+
path.each_with_index do |delete_path, index|
|
171
|
+
if index == path.length - 1 && active_path
|
172
|
+
active_path.delete(delete_path)
|
173
|
+
elsif active_path
|
174
|
+
active_path = active_path[delete_path]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
hash
|
179
|
+
end
|
180
|
+
|
181
|
+
# Base paths to check for the contrast configuration file, sorted by
|
182
|
+
# reverse order of precedence (first is most important).
|
183
|
+
def configuration_paths
|
184
|
+
@_configuration_paths ||= begin
|
185
|
+
basename = default_name.split('.').first
|
186
|
+
names = %w[yml yaml].map { |suffix| "#{ basename }.#{ suffix }" }
|
187
|
+
|
188
|
+
paths = []
|
189
|
+
paths << ENV['CONTRAST_CONFIG_PATH'] if ENV['CONTRAST_CONFIG_PATH']
|
190
|
+
paths << ENV['CONTRAST_SECURITY_CONFIG'] if ENV['CONTRAST_SECURITY_CONFIG']
|
191
|
+
|
192
|
+
tmp = CONFIG_BASE_PATHS.product(names)
|
193
|
+
paths += tmp.map!(&:join)
|
194
|
+
paths
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def deep_merge cli_config, file_config
|
199
|
+
cli_config.merge(file_config) do |_key, cli_value, file_value|
|
200
|
+
cli_value.is_a?(Hash) && file_value.is_a?(Hash) ? deep_merge(cli_value, file_value) : cli_value
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def deep_stringify_all_keys hash
|
205
|
+
return if hash.nil?
|
206
|
+
|
207
|
+
new_hash = {}
|
208
|
+
hash.each do |key, value|
|
209
|
+
new_hash[key.to_s] = value.is_a?(Hash) ? deep_stringify_all_keys(value) : value
|
210
|
+
end
|
211
|
+
new_hash
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,51 @@
|
|
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 CoreExtensions
|
6
|
+
# Our top level Protect namespace in the Core Extensions section of our
|
7
|
+
# code. These patches are those that are invoked directly from a patched
|
8
|
+
# Class.
|
9
|
+
#
|
10
|
+
# @deprecated This is one of our earliest designs and is not nearly as
|
11
|
+
# relevant given the move to C based patching and the lessons learned
|
12
|
+
# therein.
|
13
|
+
module Assess
|
14
|
+
cs__scoped_require 'contrast/agent/patching/policy/patcher'
|
15
|
+
|
16
|
+
cs__scoped_require 'contrast/utils/tag_util'
|
17
|
+
|
18
|
+
# provider rules - have to come before policy
|
19
|
+
cs__scoped_require 'contrast/agent/assess/rule/provider'
|
20
|
+
|
21
|
+
# tagging / dataflow
|
22
|
+
cs__scoped_require 'contrast/agent/assess/adjusted_span'
|
23
|
+
cs__scoped_require 'contrast/agent/assess/policy/policy_node'
|
24
|
+
cs__scoped_require 'contrast/agent/assess/policy/source_node'
|
25
|
+
cs__scoped_require 'contrast/agent/assess/policy/source_method'
|
26
|
+
cs__scoped_require 'contrast/agent/assess/policy/propagation_node'
|
27
|
+
cs__scoped_require 'contrast/agent/assess/policy/propagation_method'
|
28
|
+
cs__scoped_require 'contrast/agent/assess/policy/trigger_node'
|
29
|
+
cs__scoped_require 'contrast/agent/assess/policy/trigger_method'
|
30
|
+
cs__scoped_require 'contrast/agent/assess/policy/policy'
|
31
|
+
cs__scoped_require 'contrast/agent/assess/policy/patcher'
|
32
|
+
|
33
|
+
# classes that don't play nice w/ our standard propagation
|
34
|
+
cs__scoped_require 'contrast/agent/assess/frozen_properties'
|
35
|
+
cs__scoped_require 'contrast/core_extensions/assess/assess_extension'
|
36
|
+
# this needs to come first b/c array and others work on strings and
|
37
|
+
# expect them to be trackable
|
38
|
+
cs__scoped_require 'contrast/core_extensions/assess/string'
|
39
|
+
|
40
|
+
cs__scoped_require 'contrast/core_extensions/assess/array'
|
41
|
+
cs__scoped_require 'contrast/core_extensions/assess/erb'
|
42
|
+
cs__scoped_require 'contrast/core_extensions/assess/fiber'
|
43
|
+
cs__scoped_require 'contrast/core_extensions/assess/hash'
|
44
|
+
cs__scoped_require 'contrast/core_extensions/assess/kernel'
|
45
|
+
cs__scoped_require 'contrast/core_extensions/assess/regexp'
|
46
|
+
cs__scoped_require 'contrast/core_extensions/assess/module'
|
47
|
+
cs__scoped_require 'contrast/core_extensions/assess/basic_object'
|
48
|
+
cs__scoped_require 'contrast/core_extensions/assess/tilt_template_trigger'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
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/agent/patching/policy/patcher'
|
5
|
+
cs__scoped_require 'contrast/components/interface'
|
6
|
+
|
7
|
+
# This is our patch of the Array class required to handle propagation
|
8
|
+
# Disclaimer: there may be a better way, but we're in a 'get it work' state.
|
9
|
+
# Hopefully, we'll be in a 'get it right' state soon.
|
10
|
+
class Array
|
11
|
+
include Contrast::Components::Interface
|
12
|
+
|
13
|
+
access_component :scope
|
14
|
+
|
15
|
+
ARRAY_JOIN_HASH = {
|
16
|
+
'class_name' => 'Array',
|
17
|
+
'instance_method' => true,
|
18
|
+
'method_visibility' => 'public',
|
19
|
+
'method_name' => 'join',
|
20
|
+
'action' => 'CUSTOM',
|
21
|
+
'source' => 'O',
|
22
|
+
'target' => 'R',
|
23
|
+
'patch_class' => 'NOOP',
|
24
|
+
'patch_method' => '__cs_track_join'
|
25
|
+
}.cs__freeze
|
26
|
+
ARRAY_JOIN_NODE = Contrast::Agent::Assess::Policy::PropagationNode.new(ARRAY_JOIN_HASH)
|
27
|
+
|
28
|
+
# When you call join, they use an internal thing, so there's no good way to get at the thing being returned.
|
29
|
+
# Multiple Strings are appended with the #join method. Because that
|
30
|
+
# operation happens in C, we have to do it here rather than rely on the
|
31
|
+
# patch of our String append or concat methods.
|
32
|
+
def __cs_track_join separator, ret
|
33
|
+
return ret if Contrast::Agent::Patching::Policy::Patcher.skip_assess_analysis?
|
34
|
+
|
35
|
+
with_contrast_scope do
|
36
|
+
shift = 0
|
37
|
+
separator_length = separator.nil? ? 0 : separator.to_s.length
|
38
|
+
each do |obj|
|
39
|
+
if obj # skip nil here
|
40
|
+
ret.cs__copy_from(obj, shift)
|
41
|
+
shift += obj.to_s.length
|
42
|
+
end
|
43
|
+
shift += separator_length
|
44
|
+
end
|
45
|
+
return ret unless ret.cs__tracked?
|
46
|
+
|
47
|
+
ret.cs__properties.cleanup_tags
|
48
|
+
ret.cs__properties.build_event(
|
49
|
+
ARRAY_JOIN_NODE,
|
50
|
+
ret,
|
51
|
+
self,
|
52
|
+
ret,
|
53
|
+
[separator])
|
54
|
+
ret
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
cs__scoped_require 'cs__assess_array/cs__assess_array'
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
cs__scoped_require 'contrast/agent/assess/properties'
|
5
|
+
cs__scoped_require 'contrast/agent/assess/frozen_properties'
|
6
|
+
cs__scoped_require 'contrast/agent/assess/insulator'
|
7
|
+
|
8
|
+
module Contrast
|
9
|
+
module CoreExtensions
|
10
|
+
module Assess
|
11
|
+
# This module is responsible for maintaining the data we need to
|
12
|
+
# construct a trace event for the object in which it is included. Rather
|
13
|
+
# than have this code all over the place, any class that wants to use
|
14
|
+
# dataflow features should be sent
|
15
|
+
# 'include Contrast::CoreExtensions::Assess::AssessExtension'
|
16
|
+
module AssessExtension
|
17
|
+
include Contrast::Utils::ScopeUtil
|
18
|
+
|
19
|
+
# Lazily build properties object. Only objects that have been tracked
|
20
|
+
# will have the @_cs__properties, but all will respond to the
|
21
|
+
# cs__properties method call. You should only call this method if you
|
22
|
+
# either intend to start tracking an object or you have already checked
|
23
|
+
# cs__tracked? and it is true.
|
24
|
+
def cs__properties
|
25
|
+
# If this object was tracked before being frozen, it'll have
|
26
|
+
# mutable properties we need inside of the insulator @_cs__properties
|
27
|
+
if cs__frozen?
|
28
|
+
if instance_variable_defined?(:@_cs__properties)
|
29
|
+
@_cs__properties.properties
|
30
|
+
else
|
31
|
+
Contrast::Agent::Assess::Insulator.generate_frozen.properties
|
32
|
+
end
|
33
|
+
else
|
34
|
+
@_cs__properties ||= Contrast::Agent::Assess::Insulator.generate
|
35
|
+
@_cs__properties.properties
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def cs__properties?
|
40
|
+
instance_variable_defined?(:@_cs__properties)
|
41
|
+
end
|
42
|
+
|
43
|
+
# This is a way to check if we are already tracking an object without
|
44
|
+
# adding tracking to it. If the object already has been tracked we will
|
45
|
+
# return the tracking state of its properties. If the object hasn't
|
46
|
+
# already been tracked we will return false without starting to track
|
47
|
+
# it
|
48
|
+
def cs__tracked?
|
49
|
+
cs__properties? && cs__properties.tracked?
|
50
|
+
end
|
51
|
+
|
52
|
+
def cs__reset_properties
|
53
|
+
return unless cs__properties?
|
54
|
+
|
55
|
+
@_cs__properties = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# copy tags and info from object to self if object support methods
|
59
|
+
# obj: the object from which to copy tags and events
|
60
|
+
# shift: how far to shift the tags, negative moves left
|
61
|
+
# skip_tags: array of tags to skip copying
|
62
|
+
def cs__copy_from obj, shift = 0, skip_tags = nil
|
63
|
+
return if obj.equal?(self)
|
64
|
+
return unless Contrast::Utils::DuckUtils.quacks_to?(obj,
|
65
|
+
:cs__tracked?)
|
66
|
+
return unless obj.cs__tracked?
|
67
|
+
return if cs__properties == Contrast::Agent::Assess::Insulator.generate_frozen.properties
|
68
|
+
|
69
|
+
# This was fun to find...
|
70
|
+
# the clone and dup methods don't apply to instance variables in the
|
71
|
+
# cloned/ duped thing, so the arrays in the properties were the same.
|
72
|
+
# The most infinite of infinite loops ensued.
|
73
|
+
# DO NOT TAKE THIS OUT!
|
74
|
+
cs__reset_properties if obj.cs__properties == cs__properties
|
75
|
+
|
76
|
+
obj.cs__properties.events.each do |event|
|
77
|
+
cs__properties.events << event
|
78
|
+
end
|
79
|
+
|
80
|
+
obj.cs__properties.tag_keys.each do |key|
|
81
|
+
next if skip_tags&.include?(key)
|
82
|
+
|
83
|
+
new_tags = []
|
84
|
+
value = obj.cs__properties.fetch_tag(key)
|
85
|
+
value.each do |tag|
|
86
|
+
new_tags << tag.copy_modified(shift)
|
87
|
+
end
|
88
|
+
existing = cs__properties.fetch_tag(key)
|
89
|
+
if existing
|
90
|
+
existing.concat(new_tags)
|
91
|
+
else
|
92
|
+
cs__properties.set_tags(key, new_tags)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Some propagation occurred, but we're not sure what the
|
98
|
+
# exact transformation was. To be safe, we just explode
|
99
|
+
# all the tags from the source to the return.
|
100
|
+
#
|
101
|
+
# If the return already had that tag, the existing tag
|
102
|
+
# range is recycled to save us an object.
|
103
|
+
def cs__splat_tags ret, source = self
|
104
|
+
return unless Contrast::Utils::DuckUtils.quacks_to?(
|
105
|
+
ret,
|
106
|
+
:cs__tracked?)
|
107
|
+
|
108
|
+
splat_source = Contrast::Utils::DuckUtils.quacks_to?(
|
109
|
+
source,
|
110
|
+
:cs__tracked?)
|
111
|
+
splat_source &&= source.cs__tracked?
|
112
|
+
if splat_source
|
113
|
+
length = Contrast::Utils::StringUtils.ret_length(ret)
|
114
|
+
source.cs__properties.tag_keys.each do |key|
|
115
|
+
existing = ret.cs__properties.fetch_tag(key)
|
116
|
+
# if the tag already exists, drop all but the first range
|
117
|
+
# then change that range to cover the entire return
|
118
|
+
if existing
|
119
|
+
existing.drop(existing.length - 1)
|
120
|
+
range = existing[0]
|
121
|
+
range.repurpose(0, length)
|
122
|
+
else
|
123
|
+
span = Contrast::Agent::Assess::AdjustedSpan.new(0, length)
|
124
|
+
ret.cs__properties.add_tag(key, span)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
return unless ret.cs__tracked?
|
129
|
+
|
130
|
+
length ||= Contrast::Utils::StringUtils.ret_length(ret)
|
131
|
+
ret.cs__properties.tag_keys.each do |key|
|
132
|
+
next unless key
|
133
|
+
|
134
|
+
existing = ret.cs__properties.fetch_tag(key)
|
135
|
+
next unless existing
|
136
|
+
|
137
|
+
existing.each do |range|
|
138
|
+
range.update_end(length) if range.end_idx > length
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|