Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
python: Add standard customization setup
- modernize the sanitizer, but do not make it less specific
  • Loading branch information
yoff committed Jan 31, 2022
commit 8b5114d10e12321b1a08c8a36550844e1b46fcaa
37 changes: 24 additions & 13 deletions python/ql/lib/semmle/python/security/dataflow/LogInjection.qll
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
/**
* Provides a taint-tracking configuration for tracking untrusted user input used in log entries.
*
* Note, for performance reasons: only import this file if
* `LogInjection::Configuration` is needed, otherwise
* `LogInjectionCustomizations` should be imported instead.
*/

import python
import semmle.python.Concepts
import semmle.python.Concepts
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.RemoteFlowSources

/**
* A taint-tracking configuration for tracking untrusted user input used in log entries.
* Provides a taint-tracking configuration for tracking untrusted user input used in log entries.
*/
class LogInjectionFlowConfig extends TaintTracking::Configuration {
LogInjectionFlowConfig() { this = "LogInjectionFlowConfig" }
module LogInjection {
import LogInjectionCustomizations::LogInjection

/**
* A taint-tracking configuration for tracking untrusted user input used in log entries.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "LogInjection" }

override predicate isSource(DataFlow::Node source) { source instanceof Source }

override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }

override predicate isSink(DataFlow::Node sink) { sink = any(Logging write).getAnInput() }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }

override predicate isSanitizer(DataFlow::Node node) {
exists(CallNode call |
node.asCfgNode() = call.getFunction().(AttrNode).getObject("replace") and
call.getArg(0).getNode().(StrConst).getText() in ["\r\n", "\n"]
)
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof SanitizerGuard
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Provides default sources, sinks and sanitizers for detecting
* "command injection"
Comment thread
RasmusWL marked this conversation as resolved.
Resolved
* vulnerabilities, as well as extension points for adding your own.
*/

private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts
private import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.dataflow.new.BarrierGuards

/**
* Provides default sources, sinks and sanitizers for detecting
* "command injection"
* vulnerabilities, as well as extension points for adding your own.
*/
module LogInjection {
/**
* A data flow source for "command injection" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }

/**
* A data flow sink for "command injection" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }

/**
* A sanitizer for "command injection" vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }

/**
* A sanitizer guard for "command injection" vulnerabilities.
*/
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }

/**
* A source of remote user input, considered as a flow source.
*/
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }

/**
* A logging operation, considered as a flow sink.
*/
class LoggingAsSink extends Sink {
LoggingAsSink() { this = any(Logging write).getAnInput() }
}

/**
* A comparison with a constant string, considered as a sanitizer-guard.
*/
class StringConstCompareAsSanitizerGuard extends SanitizerGuard, StringConstCompare { }

/**
* A call to replace line breaks functions as a sanitizer.
Comment thread
yoff marked this conversation as resolved.
Resolved
*/
class ReplaceLineBreaksSanitizer extends Sanitizer, DataFlow::CallCfgNode {
ReplaceLineBreaksSanitizer() {
this.getFunction().(DataFlow::AttrRead).getAttributeName() = "replace" and
this.getArg(0).asExpr().(StrConst).getText() in ["\r\n", "\n"]
}
}
Comment on lines +59 to +72

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sanitizer check seems a bit weak. What if it only did text.replace("\r\n", "\n")? I guess it's not trivial to write a sanitizer that knows we've eliminated both, so maybe this is ok? (what are your thoughts on this)

@yoff yoff Feb 1, 2022 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have had the same concerns from the beginning.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be great to have a small comment in the code to explain this dilemma, and explain why the solution implemented was deemed ok.

}
2 changes: 1 addition & 1 deletion python/ql/src/Security/CWE-117/LogInjection.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import python
import semmle.python.security.dataflow.LogInjection
import DataFlow::PathGraph

from LogInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
from LogInjection::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to log entry.", source.getNode(),
"User-provided value"