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,379 @@
|
|
|
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/settings_state'
|
|
5
|
+
cs__scoped_require 'contrast/core_extensions/module'
|
|
6
|
+
cs__scoped_require 'contrast/utils/boolean_util'
|
|
7
|
+
|
|
8
|
+
module Contrast
|
|
9
|
+
module Agent
|
|
10
|
+
# This class functions as a way to query the Agent for its current feature
|
|
11
|
+
# set without having to expose other sections of code to the decision tree
|
|
12
|
+
# needed to make that determination.
|
|
13
|
+
class FeatureState < SettingsState
|
|
14
|
+
include Singleton
|
|
15
|
+
|
|
16
|
+
# FeatureState methods are grouped in modules,
|
|
17
|
+
# and these modules are organized roughly in ascending order
|
|
18
|
+
# according to their complexity - where more complex
|
|
19
|
+
# methods call simpler ones.
|
|
20
|
+
|
|
21
|
+
module ConfigWrappers
|
|
22
|
+
# Wrapper to provide convenience for boolean values, allowing for the
|
|
23
|
+
# handling of nil defaults that behave like true and other strange
|
|
24
|
+
# cases.
|
|
25
|
+
module Booleans
|
|
26
|
+
include Contrast::Components::Interface
|
|
27
|
+
access_component :config
|
|
28
|
+
|
|
29
|
+
# Ruby 2.4 does not nicely compare to nil, so we have to include
|
|
30
|
+
# these wrapper methods. RUBY-179 has the task to update this on
|
|
31
|
+
# EOL of 2.4 support
|
|
32
|
+
def false? config
|
|
33
|
+
Contrast::Utils::BooleanUtil.false?(config)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def true? config
|
|
37
|
+
Contrast::Utils::BooleanUtil.true?(config)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def inventory_enabled?
|
|
41
|
+
!false?(CONFIG.root.inventory.enable)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def protect_forcibly_enabled?
|
|
45
|
+
true?(CONFIG.root.protect.enable)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def protect_forcibly_disabled?
|
|
49
|
+
false?(CONFIG.root.protect.enable)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def assess_forcibly_enabled?
|
|
53
|
+
true?(CONFIG.root.assess.enable)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def assess_forcibly_disabled?
|
|
57
|
+
false?(CONFIG.root.assess.enable)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def assess_track_frozen_sources?
|
|
61
|
+
!false?(CONFIG.root.agent.ruby.track_frozen_sources)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def scan_response?
|
|
65
|
+
true?(CONFIG.root.assess.enable_scan_response)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def omit_body?
|
|
69
|
+
true?(CONFIG.root.agent.omit_body)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def require_scanning_enabled?
|
|
73
|
+
!false?(CONFIG.root.agent.ruby.require_scan)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def heap_dump_enabled?
|
|
77
|
+
true?(CONFIG.root.agent.heap_dump.enable)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def service_forcibly_disabled?
|
|
81
|
+
false?(CONFIG.root.agent.start_bundled_service)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def report_any_command_execution?
|
|
85
|
+
ctrl = protect_rule_config[Contrast::Agent::Protect::Rule::CmdInjection::NAME]
|
|
86
|
+
true?(ctrl.disable_system_commands)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def report_custom_code_sysfile_access?
|
|
90
|
+
ctrl = protect_rule_config[Contrast::Agent::Protect::Rule::PathTraversal::NAME]
|
|
91
|
+
true?(ctrl.detect_custom_code_accessing_system_files)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Determines if the Process we're currently in matches that of the
|
|
95
|
+
# Process in which the FeatureState instance was created.
|
|
96
|
+
# If it doesn't, that indicates the running context is in a new
|
|
97
|
+
# Process.
|
|
98
|
+
# @return [Boolean] if we're in the original Process in which the
|
|
99
|
+
# FeaturesState instance was initialized.
|
|
100
|
+
def in_new_process?
|
|
101
|
+
current_pid = Process.pid
|
|
102
|
+
original_pid = pid
|
|
103
|
+
current_pid != original_pid
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Wrapper for configurations regarding assess & protect rules
|
|
108
|
+
module Parameters
|
|
109
|
+
include Contrast::Components::Interface
|
|
110
|
+
access_component :settings, :config
|
|
111
|
+
|
|
112
|
+
def protect_rule_config
|
|
113
|
+
CONFIG.root.protect.rules || []
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def assess_rule_disabled? name
|
|
117
|
+
assess_disabled_rules.include? name
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def protect_rule_enabled? rule_id
|
|
121
|
+
protect_rule_mode(rule_id).to_sym != :NO_ACTION
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def assess_tags
|
|
125
|
+
CONFIG.root.assess&.tags
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def assess_disabled_rules
|
|
129
|
+
CONFIG.root.assess&.rules&.disabled_rules || SETTINGS.disabled_assess_rules || []
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def current_session_id
|
|
133
|
+
Contrast::Utils::StringUtils.force_utf8(SETTINGS.session_id)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def disabled_agent_rake_tasks
|
|
137
|
+
CONFIG.root.agent.ruby.disabled_agent_rake_tasks
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def exclusions
|
|
141
|
+
SETTINGS.exclusion_matchers
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def url_exclusions
|
|
145
|
+
exclusions.select(&:url?)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def input_exclusions
|
|
149
|
+
exclusions.select(&:input?)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def code_exclusions
|
|
153
|
+
exclusions.select(&:code?)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Wrapper for the Assess & Protect states
|
|
159
|
+
module SettingWrappers
|
|
160
|
+
include Contrast::Components::Interface
|
|
161
|
+
access_component :settings, :config
|
|
162
|
+
|
|
163
|
+
def protect_setting_enabled?
|
|
164
|
+
SETTINGS.protect_state[:enabled]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def assess_setting_enabled?
|
|
168
|
+
SETTINGS.assess_state[:enabled]
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# whether it's connected to the Contrast Service,
|
|
173
|
+
# whether config succeeded,
|
|
174
|
+
# whether writable paths are actually writeable, etc.
|
|
175
|
+
module AgentState
|
|
176
|
+
# Indicates the status of the Agent - initialized & ready - as well as
|
|
177
|
+
# the mode(s) in which it is functioning
|
|
178
|
+
module Operation
|
|
179
|
+
include Contrast::Components::Interface
|
|
180
|
+
access_component :agent
|
|
181
|
+
|
|
182
|
+
# Return true if the agent is ready to protect the application
|
|
183
|
+
def agent_ready?
|
|
184
|
+
AGENT.enabled? && connection_established? && update_received?
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def protect_enabled?
|
|
188
|
+
return false unless AGENT.enabled?
|
|
189
|
+
|
|
190
|
+
# config overrides if forcibly set
|
|
191
|
+
return false if protect_forcibly_disabled?
|
|
192
|
+
return true if protect_forcibly_enabled?
|
|
193
|
+
|
|
194
|
+
!!protect_setting_enabled?
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def assess_enabled?
|
|
198
|
+
return false unless AGENT.enabled?
|
|
199
|
+
|
|
200
|
+
# config overrides if forcibly set
|
|
201
|
+
return false if assess_forcibly_disabled?
|
|
202
|
+
return true if assess_forcibly_enabled?
|
|
203
|
+
|
|
204
|
+
!!assess_setting_enabled?
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Wrapper for the state of our Service settings and a way to access the
|
|
209
|
+
# Contrast::Agent::SocketClient responsible for interactions between
|
|
210
|
+
# the Agent & Service.
|
|
211
|
+
module Service
|
|
212
|
+
include Contrast::Components::Interface
|
|
213
|
+
access_component :agent
|
|
214
|
+
|
|
215
|
+
def service_enabled?
|
|
216
|
+
AGENT.enabled? && !service_forcibly_disabled?
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def client
|
|
220
|
+
@_client ||= Contrast::Agent::SocketClient.new
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Return true if the agent has connected with the service
|
|
224
|
+
def connection_established?
|
|
225
|
+
client.connection_established?
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Return true if the agent has processed a response from the service
|
|
229
|
+
def update_received?
|
|
230
|
+
!@last_update.nil?
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# 'Controls' synthesize all of the above into parameter sets.
|
|
236
|
+
# These can have more complex logic.
|
|
237
|
+
module Controls
|
|
238
|
+
include Contrast::Components::Interface
|
|
239
|
+
access_component :config
|
|
240
|
+
|
|
241
|
+
def heap_dump_control
|
|
242
|
+
{
|
|
243
|
+
path: File.absolute_path(CONFIG.root.agent.heap_dump.path),
|
|
244
|
+
count: CONFIG.root.agent.heap_dump.count.to_i,
|
|
245
|
+
window: CONFIG.root.agent.heap_dump.window_ms.to_f / 1000,
|
|
246
|
+
delay: CONFIG.root.agent.heap_dump.delay_ms.to_f / 1000,
|
|
247
|
+
clean: true?(CONFIG.root.agent.heap_dump.clean)
|
|
248
|
+
}
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
DEFAULT_SAMPLING_ENABLED = false
|
|
252
|
+
DEFAULT_SAMPLING_BASELINE = 5
|
|
253
|
+
DEFAULT_SAMPLING_REQUEST_FREQUENCY = 5
|
|
254
|
+
DEFAULT_SAMPLING_RESPONSE_FREQUENCY = 25
|
|
255
|
+
DEFAULT_SAMPLING_WINDOW_MS = 180_000 # 3 minutes, arbitrary value from Java agent
|
|
256
|
+
def sampling_control settings = @sampling_features
|
|
257
|
+
cas = CONFIG.root.assess&.sampling
|
|
258
|
+
|
|
259
|
+
{
|
|
260
|
+
enabled: [cas&.enable, settings&.enabled, DEFAULT_SAMPLING_ENABLED] .reject(&:nil?).first,
|
|
261
|
+
baseline: [cas&.baseline, settings&.baseline, DEFAULT_SAMPLING_BASELINE] .map(&:to_i).find(&:positive?),
|
|
262
|
+
request_frequency: [cas&.request_frequency, settings&.request_frequency, DEFAULT_SAMPLING_REQUEST_FREQUENCY] .map(&:to_i).find(&:positive?),
|
|
263
|
+
response_frequency: [cas&.response_frequency, settings&.response_frequency, DEFAULT_SAMPLING_RESPONSE_FREQUENCY].map(&:to_i).find(&:positive?),
|
|
264
|
+
window: [cas&.window_ms, settings&.window_ms, DEFAULT_SAMPLING_WINDOW_MS] .map(&:to_i).find(&:positive?)
|
|
265
|
+
}
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
DEFAULT_LOG_FILENAME = 'contrast_service.log'
|
|
269
|
+
def service_control
|
|
270
|
+
{
|
|
271
|
+
host: CONFIG.root.agent.service.host || Contrast::Configuration::DEFAULT_HOST,
|
|
272
|
+
port: CONFIG.root.agent.service.port || Contrast::Configuration::DEFAULT_PORT,
|
|
273
|
+
socket_path: CONFIG.root.agent.service.socket,
|
|
274
|
+
logger_path: CONFIG.root.agent.service.logger.path || DEFAULT_LOG_FILENAME
|
|
275
|
+
}
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def exception_control
|
|
279
|
+
{
|
|
280
|
+
enable: true?(CONFIG.root.agent.ruby.exceptions.capture),
|
|
281
|
+
status: CONFIG.root.agent.ruby.exceptions.override_status || 403,
|
|
282
|
+
message: CONFIG.root.agent.ruby.exceptions.override_message || Contrast::Utils::ObjectShare::OVERRIDE_MESSAGE
|
|
283
|
+
}
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Wrapper for the state of our diagnostics settings
|
|
288
|
+
module Diagnostic
|
|
289
|
+
include Contrast::Components::Interface
|
|
290
|
+
access_component :config
|
|
291
|
+
|
|
292
|
+
def uninstrument_namespaces
|
|
293
|
+
tmp = CONFIG.root.agent.ruby.uninstrument_namespace.map(&:to_sym)
|
|
294
|
+
tmp.select! { |sym| Object.cs__const_defined?(sym) }
|
|
295
|
+
tmp.map! { |sym| Object.cs__const_get(sym) }
|
|
296
|
+
tmp
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Wrapper for the state of our logging settings and holder for utility
|
|
301
|
+
# methods for logging state.
|
|
302
|
+
module Logging
|
|
303
|
+
include Contrast::Components::Interface
|
|
304
|
+
access_component :config
|
|
305
|
+
|
|
306
|
+
FALLBACK = STDOUT
|
|
307
|
+
LOG_INFO_RULE_SETTINGS = 'Current rule settings:'
|
|
308
|
+
# Utility method to log the current mode of all the rules
|
|
309
|
+
def log_rule_modes
|
|
310
|
+
return unless logger&.info?
|
|
311
|
+
|
|
312
|
+
logger.info(LOG_INFO_RULE_SETTINGS)
|
|
313
|
+
PROTECT.rules.each { |k, v| logger.info(".. protect:\t#{ k } (#{ v.mode })") }
|
|
314
|
+
ASSESS.rules.each { |k, v| logger.info(".. assess: \t#{ k } (#{ v.enabled? })") }
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
ENV_KEYS = %w[HOME PWD RACK_ENV RAILS_ENV RUBY_VERSION GEM_HOME GEM_PATH].cs__freeze
|
|
318
|
+
# Utility method to log some current ruby and rails information from environment
|
|
319
|
+
def log_environment
|
|
320
|
+
return unless logger.info?
|
|
321
|
+
|
|
322
|
+
logger.info "AGENT_VERSION=#{ Contrast::Agent::VERSION }"
|
|
323
|
+
ENV.each do |env_key, env_value|
|
|
324
|
+
env_key = env_key.to_s
|
|
325
|
+
next unless ENV_KEYS.include?(env_key) ||
|
|
326
|
+
(env_key.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER) &&
|
|
327
|
+
!env_key.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER + 'API'))
|
|
328
|
+
|
|
329
|
+
logger.info "#{ env_key }=#{ env_value }"
|
|
330
|
+
end
|
|
331
|
+
logger.info "PARENT_PROCESS_ID=#{ Process.ppid }"
|
|
332
|
+
logger.info "PROCESS_ID=#{ Process.pid }"
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def log_configuration
|
|
336
|
+
return unless logger.info?
|
|
337
|
+
|
|
338
|
+
loggable = CONFIG.raw.send(:load_config)
|
|
339
|
+
loggable.delete('api')
|
|
340
|
+
logger.info "LOCAL CONFIGURATION: #{ JSON.pretty_generate(loggable) }"
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
FRAMEWORKS = %w[rails sinatra grape].cs__freeze
|
|
344
|
+
WEB_SERVERS = %w[agoo falcon hoof iodine mongrel mongrel2 passenger puma rack skinny thin trinidad unicorn webrick yarn].cs__freeze
|
|
345
|
+
LIBRARIES = %w[excon json mongo moped mysql nokogiri oga ox pg psych sqlite3 typhoeus yaml].cs__freeze
|
|
346
|
+
def log_specific_libraries
|
|
347
|
+
FRAMEWORKS.each(&cs__method(:log_gem_data))
|
|
348
|
+
WEB_SERVERS.each(&cs__method(:log_gem_data))
|
|
349
|
+
LIBRARIES.each(&cs__method(:log_gem_data))
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def log_all_libraries
|
|
353
|
+
return unless logger.debug?
|
|
354
|
+
|
|
355
|
+
Gem.loaded_specs.each_pair do |_name, gem_spec|
|
|
356
|
+
logger.debug { "GEM LOADED: #{ gem_spec.name }=#{ gem_spec.version }" }
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def log_gem_data gem_name
|
|
361
|
+
gem_spec = Gem.loaded_specs[gem_name]
|
|
362
|
+
return unless gem_spec
|
|
363
|
+
|
|
364
|
+
logger.info { "GEM LOADED: #{ gem_spec.name }=#{ gem_spec.version }" }
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# Methods that query the config.
|
|
369
|
+
include ConfigWrappers::Booleans # These check boolean config options.
|
|
370
|
+
include ConfigWrappers::Parameters # These check against the config and return parameters.
|
|
371
|
+
include SettingWrappers # Methods that query settings from TeamServer.
|
|
372
|
+
include AgentState::Operation # Enable/disable the agent, ask if the agent can run.
|
|
373
|
+
include AgentState::Service # Agent's client that talks to the service.
|
|
374
|
+
include Controls # Syntheses of the above.
|
|
375
|
+
include Diagnostic # Misc.
|
|
376
|
+
include Logging # Logging.
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
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/inventory/policy/trigger_node'
|
|
5
|
+
cs__scoped_require 'contrast/agent/patching/policy/policy'
|
|
6
|
+
|
|
7
|
+
# classes required by patches in the policy
|
|
8
|
+
cs__scoped_require 'contrast/core_extensions/inventory/datastores'
|
|
9
|
+
|
|
10
|
+
module Contrast
|
|
11
|
+
module Agent
|
|
12
|
+
module Inventory
|
|
13
|
+
module Policy
|
|
14
|
+
# This is just a holder for our policy. Takes the policy JSON and
|
|
15
|
+
# converts it into hashes that we can access nicely
|
|
16
|
+
class Policy < Contrast::Agent::Patching::Policy::Policy
|
|
17
|
+
def self.policy_folder
|
|
18
|
+
'inventory'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def disabled_globally?
|
|
22
|
+
!INVENTORY.enabled?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def node_type
|
|
26
|
+
Contrast::Agent::Inventory::Policy::TriggerNode
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
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 'contrast/agent/patching/policy/trigger_node'
|
|
5
|
+
|
|
6
|
+
module Contrast
|
|
7
|
+
module Agent
|
|
8
|
+
module Inventory
|
|
9
|
+
module Policy
|
|
10
|
+
# This class functions to translate our policy.json into an actionable
|
|
11
|
+
# Ruby object, allowing for dynamic patching over hardcoded patching,
|
|
12
|
+
# specifically for those methods which result in the trigger of an
|
|
13
|
+
# event interesting to the design of the application.
|
|
14
|
+
class TriggerNode < Contrast::Agent::Patching::Policy::TriggerNode
|
|
15
|
+
def feature
|
|
16
|
+
'Inventory'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
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
|
+
cs__scoped_require 'logger'
|
|
5
|
+
|
|
6
|
+
cs__scoped_require 'contrast/core_extensions/module'
|
|
7
|
+
cs__scoped_require 'contrast/components/interface'
|
|
8
|
+
|
|
9
|
+
module Contrast
|
|
10
|
+
module Agent
|
|
11
|
+
# This class functions to serve as a wrapper around our logging, as we need
|
|
12
|
+
# to be able to dynamically update level based on updates to TeamServer.
|
|
13
|
+
class LoggerManager
|
|
14
|
+
include Contrast::Components::Interface
|
|
15
|
+
access_component :app_context, :logging, :config
|
|
16
|
+
|
|
17
|
+
DEFAULT_NAME = 'contrast.log'
|
|
18
|
+
DEFAULT_LEVEL = ::Logger::INFO
|
|
19
|
+
VALID_LEVELS = %w[INFO WARN DEBUG FATAL UNKNOWN ERROR].cs__freeze
|
|
20
|
+
STDOUT_STR = 'STDOUT'
|
|
21
|
+
STDERR_STR = 'STDERR'
|
|
22
|
+
|
|
23
|
+
attr_reader :current,
|
|
24
|
+
:previous_path,
|
|
25
|
+
:previous_level
|
|
26
|
+
|
|
27
|
+
def initialize
|
|
28
|
+
update
|
|
29
|
+
rescue StandardError => e
|
|
30
|
+
Contrast::Agent::FeatureState::Logging::FALLBACK.puts 'Unable to initialize regular logger in LoggerManager.'
|
|
31
|
+
Contrast::Agent::FeatureState::Logging::FALLBACK.puts e.backtrace.join(Contrast::Utils::ObjectShare::NEW_LINE)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def update log_file = nil, log_level = nil
|
|
35
|
+
config = CONFIG.root.agent.logger
|
|
36
|
+
|
|
37
|
+
config_path = config.path&.length.to_i.positive? ? config.path : nil
|
|
38
|
+
config_level = config.level&.length&.positive? ? config.level : nil
|
|
39
|
+
|
|
40
|
+
# config > settings > default
|
|
41
|
+
path = valid_path(config_path || log_file)
|
|
42
|
+
level_const = valid_level(config_level || log_level)
|
|
43
|
+
|
|
44
|
+
# don't needlessly recreate logger
|
|
45
|
+
return if @current && (path == previous_path) && (level_const == previous_level)
|
|
46
|
+
|
|
47
|
+
@previous_path = path
|
|
48
|
+
@previous_level = level_const
|
|
49
|
+
|
|
50
|
+
@current = build(path: path, level_const: level_const)
|
|
51
|
+
|
|
52
|
+
@current.debug { 'Initialized new contrast agent logger' }
|
|
53
|
+
|
|
54
|
+
self
|
|
55
|
+
rescue StandardError => e
|
|
56
|
+
Contrast::Agent::FeatureState::Logging::FALLBACK.puts 'Unable to process update to LoggerManager.'
|
|
57
|
+
Contrast::Agent::FeatureState::Logging::FALLBACK.puts e.backtrace.join(Contrast::Utils::ObjectShare::NEW_LINE)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def default_progname
|
|
63
|
+
"Contrast #{ APP_CONTEXT.name }"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def build path: STDOUT_STR, progname: default_progname, level_const: DEFAULT_LEVEL
|
|
67
|
+
current = case path
|
|
68
|
+
when STDOUT_STR, STDERR_STR
|
|
69
|
+
::Logger.new(Object.cs__const_get(path))
|
|
70
|
+
else
|
|
71
|
+
::Logger.new(path)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
current.progname = progname
|
|
75
|
+
current.level = level_const
|
|
76
|
+
|
|
77
|
+
current.formatter = proc do |severity_f, datetime_f, progname_f, msg_f|
|
|
78
|
+
"#{ datetime_f.strftime('%Y-%m-%d %H:%M:%S,%L') } [#{ progname_f }] #{ severity_f } - #{ msg_f }\n"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
current
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def valid_path path
|
|
85
|
+
path = path.nil? ? Contrast::Utils::ObjectShare::EMPTY_STRING : path
|
|
86
|
+
return path if path == STDOUT_STR
|
|
87
|
+
return path if path == STDERR_STR
|
|
88
|
+
|
|
89
|
+
path = DEFAULT_NAME if path.empty?
|
|
90
|
+
if Contrast::Utils::IOUtil.write_permission?(path)
|
|
91
|
+
path
|
|
92
|
+
else
|
|
93
|
+
if File.directory?(path)
|
|
94
|
+
Contrast::Agent::FeatureState::Logging::FALLBACK.puts "Unable to create log in directory: #{ path }. \n Writing to standard out instead"
|
|
95
|
+
else
|
|
96
|
+
Contrast::Agent::FeatureState::Logging::FALLBACK.puts "Unable to write to log file: #{ path } \n Writing to standard out instead"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
STDOUT_STR
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def valid_level level
|
|
104
|
+
level = level.nil? ? DEFAULT_LEVEL : level
|
|
105
|
+
level = 'DEBUG' if level == 'TRACE'
|
|
106
|
+
if VALID_LEVELS.include?(level)
|
|
107
|
+
Object.cs__const_get("::Logger::#{ level }")
|
|
108
|
+
else
|
|
109
|
+
DEFAULT_LEVEL
|
|
110
|
+
end
|
|
111
|
+
rescue StandardError
|
|
112
|
+
DEFAULT_LEVEL
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|