ruby.rails.security.audit.avoid-tainted-ftp-call.avoid-tainted-ftp-call
semgrep
Author
unknown
Download Count*
License
Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to.
Run Locally
Run in CI
Defintion
rules:
- id: avoid-tainted-ftp-call
metadata:
owasp:
- A05:2017 - Broken Access Control
- A01:2021 - Broken Access Control
cwe:
- "CWE-22: Improper Limitation of a Pathname to a Restricted Directory
('Path Traversal')"
references:
- https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown
category: security
technology:
- rails
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Path Traversal
message: Using user input when accessing files is potentially dangerous. A
malicious actor could use this to modify or access files they have no
right to.
languages:
- ruby
severity: WARNING
mode: taint
pattern-sources:
- pattern: params
- pattern: cookies
- pattern: request.env
pattern-sinks:
- pattern-either:
- pattern: Net::FTP.$X(...)
- patterns:
- pattern-inside: |
$FTP = Net::FTP.$OPEN(...)
...
$FTP.$METHOD(...)
- pattern: $FTP.$METHOD(...)
Examples
avoid-tainted-ftp-call.rb
require 'net/ftp'
def foo
host = params[:host]
# ruleid: avoid-tainted-ftp-call
ftp = Net::FTP.new(host)
# ruleid: avoid-tainted-ftp-call
ftp = Net::FTP.open(params[:host])
ftp = Net::FTP.new()
# ruleid: avoid-tainted-ftp-call
ftp.connect(params[:host])
# ruleid: avoid-tainted-ftp-call
ftp.get("/tmp/#{params[:file]}")
# ruleid: avoid-tainted-ftp-call
ftp.getbinaryfile("/tmp/#{params[:file]}")
# ruleid: avoid-tainted-ftp-call
ftp.gettextfile("/tmp/#{params[:file]}")
# ruleid: avoid-tainted-ftp-call
ftp.put("/tmp/#{params[:file]}")
# ruleid: avoid-tainted-ftp-call
ftp.putbinaryfile("/tmp/#{params[:file]}")
# ruleid: avoid-tainted-ftp-call
ftp.puttextfile("/tmp/#{params[:file]}")
# ruleid: avoid-tainted-ftp-call
ftp.delete("/tmp/#{params[:file]}")
# ruleid: avoid-tainted-ftp-call
ftp.storlines(params[:cmd], "/tmp/log")
# ruleid: avoid-tainted-ftp-call
ftp.storbinary(params[:cmd], "/tmp/log")
# ruleid: avoid-tainted-ftp-call
ftp.sendcmd(params[:cmd])
# ruleid: avoid-tainted-ftp-call
ftp.retrlines(params[:cmd])
# ruleid: avoid-tainted-ftp-call
ftp.retrbinary(params[:cmd], 1024)
# ok: avoid-tainted-ftp-call
ftp = Net::FTP.new("example.com")
# ok: avoid-tainted-ftp-call
ftp = Net::FTP.open("example.com")
ftp = Net::FTP.new()
# ok: avoid-tainted-ftp-call
ftp.connect("example.com")
# ok: avoid-tainted-ftp-call
ftp.get("/tmp/file")
# ok: avoid-tainted-ftp-call
ftp.getbinaryfile("/tmp/file")
# ok: avoid-tainted-ftp-call
ftp.gettextfile("/tmp/file")
# ok: avoid-tainted-ftp-call
ftp.put("/tmp/file")
# ok: avoid-tainted-ftp-call
ftp.putbinaryfile("/tmp/file")
# ok: avoid-tainted-ftp-call
ftp.puttextfile("/tmp/file")
# ok: avoid-tainted-ftp-call
ftp.delete("/tmp/file")
# ok: avoid-tainted-ftp-call
ftp.storlines("ls -al", "/tmp/log")
# ok: avoid-tainted-ftp-call
ftp.storbinary("ls -al", "/tmp/log")
# ok: avoid-tainted-ftp-call
ftp.sendcmd("ls -al")
# ok: avoid-tainted-ftp-call
ftp.retrlines("ls -al")
end
Short Link: https://sg.run/Q9gP