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,104 @@
|
|
|
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
|
+
# This module is used to analyze non-rails session storage configuration for assess vulnerabilities
|
|
9
|
+
module RackAssessSessionCookie
|
|
10
|
+
include Contrast::Components::Interface
|
|
11
|
+
|
|
12
|
+
access_component :analysis, :logging, :scope
|
|
13
|
+
|
|
14
|
+
CS__SECURE_RULE_NAME = 'secure-flag-missing'
|
|
15
|
+
CS__HTTPONLY_NAME = 'rails-http-only-disabled'
|
|
16
|
+
CS__SESSION_TIMEOUT_NAME = 'session-timeout'
|
|
17
|
+
SAFE_SESSION_TIMEOUT = (30 * 60 * 60)
|
|
18
|
+
class << self
|
|
19
|
+
include Contrast::Utils::InvalidConfigurationUtil
|
|
20
|
+
|
|
21
|
+
def analyze_cookie_initialization options
|
|
22
|
+
return if PROTECT.enabled?
|
|
23
|
+
|
|
24
|
+
apply_session_timeout(options)
|
|
25
|
+
apply_httponly(options)
|
|
26
|
+
apply_secure_session(options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def vulnerable_setting?(setting_key,
|
|
30
|
+
safe_settings_value,
|
|
31
|
+
options, safe_default: true,
|
|
32
|
+
comparison_type: nil)
|
|
33
|
+
# In most cases, Rack is pretty nice and the default value is safe
|
|
34
|
+
return !safe_default unless options&.key?(setting_key)
|
|
35
|
+
|
|
36
|
+
value = options[setting_key]
|
|
37
|
+
|
|
38
|
+
return value.to_i > safe_settings_value.to_i if comparison_type&.to_sym == :greater_than
|
|
39
|
+
|
|
40
|
+
value != safe_settings_value
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def apply_secure_session options
|
|
44
|
+
return unless vulnerable_setting?(
|
|
45
|
+
:secure,
|
|
46
|
+
true,
|
|
47
|
+
options,
|
|
48
|
+
safe_default: false)
|
|
49
|
+
|
|
50
|
+
with_contrast_scope do
|
|
51
|
+
cs__report_finding(
|
|
52
|
+
CS__SECURE_RULE_NAME,
|
|
53
|
+
options,
|
|
54
|
+
caller_locations(10, 9)[0])
|
|
55
|
+
end
|
|
56
|
+
rescue StandardError => e
|
|
57
|
+
begin
|
|
58
|
+
logger.log_error('Unable to track call to secure session', e)
|
|
59
|
+
rescue StandardError
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def apply_session_timeout options
|
|
65
|
+
return unless vulnerable_setting?(:expire_after,
|
|
66
|
+
SAFE_SESSION_TIMEOUT,
|
|
67
|
+
options,
|
|
68
|
+
safe_default: false,
|
|
69
|
+
comparison_type: :greater_than)
|
|
70
|
+
|
|
71
|
+
with_contrast_scope do
|
|
72
|
+
cs__report_finding(
|
|
73
|
+
CS__SESSION_TIMEOUT_NAME,
|
|
74
|
+
options,
|
|
75
|
+
caller_locations(10, 9)[0])
|
|
76
|
+
end
|
|
77
|
+
rescue StandardError => e
|
|
78
|
+
begin
|
|
79
|
+
logger.log_error('Unable to track call to set session timeout', e)
|
|
80
|
+
rescue StandardError
|
|
81
|
+
nil
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def apply_httponly options
|
|
86
|
+
return unless vulnerable_setting?(:httponly, true, options)
|
|
87
|
+
|
|
88
|
+
with_contrast_scope do
|
|
89
|
+
cs__report_finding(
|
|
90
|
+
CS__HTTPONLY_NAME,
|
|
91
|
+
options,
|
|
92
|
+
caller_locations(10, 9)[0])
|
|
93
|
+
end
|
|
94
|
+
rescue StandardError => e
|
|
95
|
+
begin
|
|
96
|
+
logger.log_error('Unable to track call to httponly', e)
|
|
97
|
+
rescue StandardError
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
# This module is used to analyze rails session storage configuration for assess vulnerabilities
|
|
9
|
+
module RailsAssessConfiguration
|
|
10
|
+
include Contrast::Components::Interface
|
|
11
|
+
|
|
12
|
+
access_component :analysis, :logging, :scope
|
|
13
|
+
|
|
14
|
+
CS__SESSION_TIMEOUT_NAME = 'session-timeout'
|
|
15
|
+
SAFE_SESSION_TIMEOUT = (30 * 60 * 1000)
|
|
16
|
+
CS__SECURE_RULE_NAME = 'secure-flag-missing'
|
|
17
|
+
CS__HTTPONLY_RULE_NAME = 'rails-http-only-disabled'
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
include Contrast::Utils::InvalidConfigurationUtil
|
|
21
|
+
|
|
22
|
+
def analyze_session_store *args
|
|
23
|
+
return if PROTECT.enabled?
|
|
24
|
+
|
|
25
|
+
apply_httponly_disabled(*args)
|
|
26
|
+
apply_secure_cookie_disabled(*args)
|
|
27
|
+
apply_session_timeout(*args)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def vulnerable_setting? setting_key, safe_settings_value, original_args, safe_default: true, comparison_type: nil
|
|
31
|
+
# In most cases, Rails is pretty nice and the default value is safe
|
|
32
|
+
return !safe_default unless original_args && original_args.length > 1
|
|
33
|
+
|
|
34
|
+
# If the user overrode some args, but not ours, fall back on the default
|
|
35
|
+
rails_session_settings = original_args[1]
|
|
36
|
+
return !safe_default unless rails_session_settings&.key?(setting_key)
|
|
37
|
+
|
|
38
|
+
value = rails_session_settings[setting_key]
|
|
39
|
+
|
|
40
|
+
return value.to_i > safe_settings_value.to_i if comparison_type&.to_sym == :greater_than
|
|
41
|
+
|
|
42
|
+
value != safe_settings_value
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def apply_session_timeout *args
|
|
46
|
+
return if ASSESS.rule_disabled? CS__SESSION_TIMEOUT_NAME
|
|
47
|
+
return unless vulnerable_setting?(:expire_after, SAFE_SESSION_TIMEOUT, args, comparison_type: :greater_than, safe_default: false)
|
|
48
|
+
|
|
49
|
+
rails_session_settings = args[1]
|
|
50
|
+
with_contrast_scope do
|
|
51
|
+
cs__report_finding(CS__SESSION_TIMEOUT_NAME, rails_session_settings, caller_locations(5, 4)[0])
|
|
52
|
+
end
|
|
53
|
+
rescue StandardError => e
|
|
54
|
+
begin
|
|
55
|
+
logger.log_error('Unable to track call to set session timeout', e)
|
|
56
|
+
rescue StandardError
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def apply_secure_cookie_disabled *args
|
|
62
|
+
return if ASSESS.rule_disabled? CS__SECURE_RULE_NAME
|
|
63
|
+
return unless vulnerable_setting?(:secure, true, args)
|
|
64
|
+
|
|
65
|
+
rails_session_settings = args[1]
|
|
66
|
+
with_contrast_scope do
|
|
67
|
+
cs__report_finding(CS__SECURE_RULE_NAME, rails_session_settings, caller_locations(5, 4)[0])
|
|
68
|
+
end
|
|
69
|
+
rescue StandardError => e
|
|
70
|
+
begin
|
|
71
|
+
logger.log_error('Unable to track call to disable secure cookies', e)
|
|
72
|
+
rescue StandardError
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def apply_httponly_disabled *args
|
|
78
|
+
return if ASSESS.rule_disabled? CS__HTTPONLY_RULE_NAME
|
|
79
|
+
return unless vulnerable_setting?(:httponly, true, args)
|
|
80
|
+
|
|
81
|
+
rails_session_settings = args[1]
|
|
82
|
+
with_contrast_scope do
|
|
83
|
+
cs__report_finding(CS__HTTPONLY_RULE_NAME, rails_session_settings, caller_locations(5, 4)[0])
|
|
84
|
+
end
|
|
85
|
+
rescue StandardError => e
|
|
86
|
+
begin
|
|
87
|
+
logger.log_error('Unable to track call to disable httponly in session cookie', e)
|
|
88
|
+
rescue StandardError
|
|
89
|
+
nil
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
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
|
+
cs__scoped_require 'securerandom'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Utils
|
|
8
|
+
# Utilites for generating random strings
|
|
9
|
+
class RandomUtil
|
|
10
|
+
RANDOM_CHARS = (('0'..'9').to_a + ('A'..'Z').to_a).cs__freeze
|
|
11
|
+
RANDOM_LENGTH = RANDOM_CHARS.length
|
|
12
|
+
|
|
13
|
+
def self.secure_random_string len
|
|
14
|
+
arr = []
|
|
15
|
+
len.to_i.times do
|
|
16
|
+
arr << RANDOM_CHARS[SecureRandom.random_number(RANDOM_LENGTH)]
|
|
17
|
+
end
|
|
18
|
+
arr.join
|
|
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 Utils
|
|
6
|
+
# ResourceLoader can attempt to read a file from a predefined resource directory
|
|
7
|
+
class ResourceLoader
|
|
8
|
+
RESOURCES = 'resources'
|
|
9
|
+
|
|
10
|
+
# __FILE__/../../../resources
|
|
11
|
+
RESOURCE_ROOT = File.join(
|
|
12
|
+
File.dirname(__FILE__),
|
|
13
|
+
Contrast::Utils::ObjectShare::PARENT_PATH,
|
|
14
|
+
Contrast::Utils::ObjectShare::PARENT_PATH,
|
|
15
|
+
Contrast::Utils::ObjectShare::PARENT_PATH,
|
|
16
|
+
RESOURCES).cs__freeze
|
|
17
|
+
|
|
18
|
+
def self.load resource
|
|
19
|
+
File.read(File.join(RESOURCE_ROOT, resource))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
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 'parser/current'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Utils
|
|
8
|
+
# This utility allows us to parse and rewrite the AST in Ruby 2.4 & 2.5,
|
|
9
|
+
# allowing us to track String interpolation propagation by replacing those
|
|
10
|
+
# events with String#+ events instead.
|
|
11
|
+
class RubyAstRewriter < Parser::TreeRewriter
|
|
12
|
+
VARIABLES = %i[ivar cvar gvar].cs__freeze
|
|
13
|
+
|
|
14
|
+
# Rewrite the given source_string, converting the interpolation action
|
|
15
|
+
# therein to a concatenation action
|
|
16
|
+
#
|
|
17
|
+
# @param source_string [String] the String to rewrite
|
|
18
|
+
# @return [String] either the rewritten string or the original on error.
|
|
19
|
+
def rewrite source_string
|
|
20
|
+
ast = Parser::CurrentRuby.parse(source_string)
|
|
21
|
+
buffer = Parser::Source::Buffer.new('rewrite')
|
|
22
|
+
buffer.source = source_string
|
|
23
|
+
begin
|
|
24
|
+
super(buffer, ast)
|
|
25
|
+
rescue StandardError => _e
|
|
26
|
+
source_string
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# This overloads the on_dstr method in Parser::AST::Processor to handle
|
|
31
|
+
# the replace within the given node.
|
|
32
|
+
def on_dstr node
|
|
33
|
+
return if node.children.all? { |child_node| child_node.type == :str }
|
|
34
|
+
|
|
35
|
+
new_content = '('
|
|
36
|
+
node.children.each_with_index do |child_node, index|
|
|
37
|
+
# A begin node looks like #{some_code} in ruby, we do a substring
|
|
38
|
+
# from [2...-1] to get rid of the #{ & trailing }.
|
|
39
|
+
if child_node.type == :begin
|
|
40
|
+
code = child_node.
|
|
41
|
+
location.
|
|
42
|
+
expression.
|
|
43
|
+
source_buffer.
|
|
44
|
+
source[child_node.location.begin.begin_pos...child_node.location.end.end_pos]
|
|
45
|
+
code = code[2...-1]
|
|
46
|
+
new_content += "((#{ code }).to_s)"
|
|
47
|
+
|
|
48
|
+
# For interpolations that use class, instance, or global variables,
|
|
49
|
+
# those are NOT within a begin block, but instead are a ivar, cvar,
|
|
50
|
+
# or gvar node, not stripping of interpolation markers required.
|
|
51
|
+
elsif VARIABLES.include?(child_node.type)
|
|
52
|
+
variable = child_node.children.first
|
|
53
|
+
new_content << "((#{ variable }).to_s)"
|
|
54
|
+
|
|
55
|
+
# When interpolation includes strings before or after an
|
|
56
|
+
# interpolation they are simple :str nodes, in order to preserve
|
|
57
|
+
# escaping we need to do a dump of the string value.
|
|
58
|
+
elsif child_node.type == :str
|
|
59
|
+
literal_value = child_node.children.first
|
|
60
|
+
literal_value = literal_value.dump[1...-1]
|
|
61
|
+
new_content << "\"#{ literal_value }\""
|
|
62
|
+
end
|
|
63
|
+
new_content << ' + ' unless index == node.children.length - 1
|
|
64
|
+
end
|
|
65
|
+
new_content << ')'
|
|
66
|
+
if node.location.cs__respond_to?(:heredoc_body)
|
|
67
|
+
replace(node.location.heredoc_body, new_content)
|
|
68
|
+
else
|
|
69
|
+
replace(node.location.expression, new_content)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
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 Kernel # :nodoc:
|
|
7
|
+
include Contrast::Components::Interface
|
|
8
|
+
|
|
9
|
+
access_component :scope
|
|
10
|
+
|
|
11
|
+
alias_method :cs__catch, :catch
|
|
12
|
+
|
|
13
|
+
# In the event of a `throw`, we need to override `catch`
|
|
14
|
+
# to save & restore scope state:
|
|
15
|
+
#
|
|
16
|
+
# scope_level == 0
|
|
17
|
+
#
|
|
18
|
+
# catch(:abc) do
|
|
19
|
+
# with_contrast_scope do
|
|
20
|
+
# throw :abc # will leak
|
|
21
|
+
# end
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# scope_level == 1
|
|
25
|
+
#
|
|
26
|
+
# While this will fix /all/ scope leaks, not just ones caused by `throw`,
|
|
27
|
+
# it shouldn't be relied upon as a catch-all (lmao) solution.
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def catch *args, &block
|
|
32
|
+
# Save current scope level
|
|
33
|
+
scope_level = SCOPE.scope_for_current_ec.instance_variable_get(:@contrast_scope)
|
|
34
|
+
|
|
35
|
+
# Run original catch with block.
|
|
36
|
+
retval = cs__catch(*args, &block)
|
|
37
|
+
|
|
38
|
+
# Restore scope.
|
|
39
|
+
SCOPE.scope_for_current_ec.instance_variable_set(:@contrast_scope, scope_level)
|
|
40
|
+
|
|
41
|
+
retval
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# ScopeUtil should probably be merged into Scope component.
|
|
46
|
+
module Contrast
|
|
47
|
+
module Utils
|
|
48
|
+
module ScopeUtil # :nodoc:
|
|
49
|
+
include Contrast::Components::Interface
|
|
50
|
+
|
|
51
|
+
access_component :analysis, :scope
|
|
52
|
+
|
|
53
|
+
# @return [Boolean]
|
|
54
|
+
def skip_contrast_analysis?
|
|
55
|
+
return true if in_contrast_scope?
|
|
56
|
+
return true unless Contrast::Agent::REQUEST_TRACKER.current&.analyze_request?
|
|
57
|
+
|
|
58
|
+
false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Skip if we should skip_contrast_analysis?, sampling says to ignore this
|
|
62
|
+
# request, or assess has been disabled.
|
|
63
|
+
#
|
|
64
|
+
# @return [Boolean]
|
|
65
|
+
def skip_assess_analysis?
|
|
66
|
+
return true if skip_contrast_analysis?
|
|
67
|
+
|
|
68
|
+
current_context = Contrast::Agent::REQUEST_TRACKER.current
|
|
69
|
+
return true unless current_context.analyze_request?
|
|
70
|
+
|
|
71
|
+
!ASSESS.enabled?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def cs__enter_scope
|
|
75
|
+
enter_contrast_scope!
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def cs__leave_scope
|
|
79
|
+
exit_contrast_scope!
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def cs__enter_assess_scope
|
|
83
|
+
# If we shouldn't be doing assess things, don't propagate or whatever
|
|
84
|
+
disable_contrast = skip_assess_analysis?
|
|
85
|
+
return nil if disable_contrast
|
|
86
|
+
|
|
87
|
+
enter_contrast_scope!
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def cs__enter_scope_contrast_patch
|
|
91
|
+
# If we're already in Contrast scope, don't propagate or whatever
|
|
92
|
+
disable_contrast = skip_contrast_analysis?
|
|
93
|
+
return nil if disable_contrast
|
|
94
|
+
|
|
95
|
+
enter_contrast_scope!
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Contrast
|
|
5
|
+
module Utils
|
|
6
|
+
# Utility class for processing responses from the Contrast Service. Specifically, this class
|
|
7
|
+
# processes Server and Application settings and updates the Settings component.
|
|
8
|
+
module ServiceResponseUtil
|
|
9
|
+
include Contrast::Components::Interface
|
|
10
|
+
access_component :contrast_service, :logging, :settings, :analysis
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# TODO: RUBY-119
|
|
14
|
+
def process_response response
|
|
15
|
+
fs = Contrast::Agent::FeatureState.instance
|
|
16
|
+
fs.last_update = response&.sent_ms
|
|
17
|
+
server_features = process_server_response(response)
|
|
18
|
+
app_settings = process_application_response(response)
|
|
19
|
+
|
|
20
|
+
# ReactionProcessor is a design pattern from TeamServer.
|
|
21
|
+
# Right now, there's one potential reaction, which is disabling the agent
|
|
22
|
+
Contrast::Agent::ReactionProcessor.process(response&.application_settings)
|
|
23
|
+
# Determine new accumulator state
|
|
24
|
+
if (new_accum = response&.accumulator_settings)
|
|
25
|
+
SETTINGS.accumulator_settings.replace(new_accum)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
fs.logger_manager.update(server_features&.log_file, server_features&.log_level)
|
|
29
|
+
update_features(server_features, app_settings)
|
|
30
|
+
logger.debug("Agent modes: P-#{ fs.protect_enabled? ? 'ENABLED' : 'DISABLED' }, A-#{ fs.assess_enabled? ? 'ENABLED' : 'DISABLED' }")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# Given some protobuf messages, update settings.
|
|
36
|
+
# This is the bridge between Contrast Service <-> Settings.
|
|
37
|
+
LOG_SERVER_SETTINGS_UPDATE = 'Agent: Received updated server features'
|
|
38
|
+
LOG_UPDATE_PROTECT = 'Updating Protect state'
|
|
39
|
+
LOG_UPDATE_ASSESS = 'Updating Assess state'
|
|
40
|
+
def process_server_response response
|
|
41
|
+
server_features = response&.server_features
|
|
42
|
+
return unless server_features
|
|
43
|
+
|
|
44
|
+
logger.debug(LOG_SERVER_SETTINGS_UPDATE)
|
|
45
|
+
# 'defend' is legacy for 'protect' in the dtm.
|
|
46
|
+
protect = server_features.defend
|
|
47
|
+
assess = server_features.assess
|
|
48
|
+
|
|
49
|
+
protect_enable = !!protect.enabled
|
|
50
|
+
assess_enable = !!assess.enabled
|
|
51
|
+
|
|
52
|
+
# protect
|
|
53
|
+
begin
|
|
54
|
+
logger.debug(LOG_UPDATE_PROTECT)
|
|
55
|
+
SETTINGS.protect_state[:enabled] = protect_enable
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# assess
|
|
59
|
+
begin
|
|
60
|
+
logger.debug(LOG_UPDATE_ASSESS)
|
|
61
|
+
SETTINGS.assess_state[:enabled] = assess_enable
|
|
62
|
+
SETTINGS.assess_state[:sampling_settings] = assess.sampling
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
server_features
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
MODE_WHITELIST = %i[NO_ACTION BLOCK_AT_PERIMETER MONITOR BLOCK].cs__freeze
|
|
69
|
+
LOG_APP_SETTINGS_UPDATE = 'Agent: Received updated application settings'
|
|
70
|
+
def process_application_response response
|
|
71
|
+
app_settings = response&.application_settings
|
|
72
|
+
return unless app_settings
|
|
73
|
+
|
|
74
|
+
logger.debug(LOG_APP_SETTINGS_UPDATE)
|
|
75
|
+
exclusion_matchers = app_settings.exclusions.map { |exc| Contrast::Agent::ExclusionMatcher.new(exc) }
|
|
76
|
+
protection_rules = app_settings.protection_rules.map { |pr, _hash| [pr.id, pr.mode] }
|
|
77
|
+
protection_rules.select! { |(_id, mode)| MODE_WHITELIST.include? mode }
|
|
78
|
+
modes_by_id = protection_rules.to_h
|
|
79
|
+
SETTINGS.application_state.merge!(
|
|
80
|
+
modes_by_id: modes_by_id,
|
|
81
|
+
exclusion_matchers: exclusion_matchers,
|
|
82
|
+
disabled_assess_rules: app_settings.disabled_assess_rules,
|
|
83
|
+
session_id: app_settings.session_id)
|
|
84
|
+
|
|
85
|
+
app_settings
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# This is can also go into settings/c.service, but it
|
|
89
|
+
# requires protobuf decorators to be pretty and decomposed.
|
|
90
|
+
LOG_INFO_RULE_SETTINGS = 'Current rule settings:'
|
|
91
|
+
def update_features server_features, app_settings
|
|
92
|
+
if !!(server_features || app_settings)
|
|
93
|
+
logger.debug_with_time('Rebuilding rule modes') do
|
|
94
|
+
SETTINGS.build_protect_rules if PROTECT.enabled?
|
|
95
|
+
SETTINGS.build_assess_rules if ASSESS.enabled?
|
|
96
|
+
|
|
97
|
+
logger.info(LOG_INFO_RULE_SETTINGS)
|
|
98
|
+
PROTECT.rules.each { |k, v| logger.info(".. protect: #{ k } (#{ v.mode })") }
|
|
99
|
+
ASSESS.rules.each { |k, v| logger.info(".. assess: #{ k } (#{ v.enabled? })") }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if (dynamic_sources_map_pb = server_features&.assess&.dynamic_sources_map)
|
|
104
|
+
dynamic_sources_map = dynamic_sources_map_pb.keys.inject({}) do |hsh, key|
|
|
105
|
+
hsh[key] = dynamic_sources_map_pb[key]
|
|
106
|
+
end
|
|
107
|
+
Contrast::Agent::Assess::Policy::Policy.instance.update_dynamic_sources dynamic_sources_map
|
|
108
|
+
end
|
|
109
|
+
# This is for assess
|
|
110
|
+
# PERF, we could avoid here with dirty-tracking.
|
|
111
|
+
Contrast::Utils::Assess::SamplingUtil.instance.update
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|