use crate::ir::TaintGraph;
use crate::labels::{label_node, LabelSet, SanitizerDef, SinkDef, SourceDef};
pub fn default_label_set() -> LabelSet {
LabelSet {
sources: vec![
SourceDef { id: "python-os-environ".into(), pattern: "os.environ".into(), category: "credential".into() },
SourceDef { id: "python-os-getenv".into(), pattern: "os.getenv".into(), category: "credential".into() },
SourceDef { id: "python-sys-argv".into(), pattern: "sys.argv".into(), category: "cli".into() },
SourceDef { id: "python-open-read".into(), pattern: "open.read".into(), category: "file".into() },
SourceDef { id: "python-pathlib-read-text".into(), pattern: "pathlib.Path.read_text".into(), category: "file".into() },
SourceDef { id: "python-request-form".into(), pattern: "request.form".into(), category: "http".into() },
SourceDef { id: "python-request-args".into(), pattern: "request.args".into(), category: "http".into() },
SourceDef { id: "python-request-json".into(), pattern: "request.json".into(), category: "http".into() },
SourceDef { id: "python-request-json-get".into(), pattern: "request.json.get".into(), category: "http".into() },
SourceDef { id: "python-request-args-get".into(), pattern: "request.args.get".into(), category: "http".into() },
SourceDef { id: "python-request-form-get".into(), pattern: "request.form.get".into(), category: "http".into() },
SourceDef { id: "python-os-environ-get".into(), pattern: "os.environ.get".into(), category: "credential".into() },
SourceDef { id: "python-input".into(), pattern: "input".into(), category: "cli".into() },
SourceDef { id: "python-pypirc".into(), pattern: ".pypirc".into(), category: "sensitive-file".into() },
SourceDef { id: "python-pip-conf".into(), pattern: "pip.conf".into(), category: "sensitive-file".into() },
SourceDef { id: "python-ssh-dir".into(), pattern: ".ssh/".into(), category: "sensitive-file".into() },
SourceDef { id: "python-aws-creds".into(), pattern: ".aws/credentials".into(), category: "sensitive-file".into() },
SourceDef { id: "python-chrome-cookies".into(), pattern: "Cookies".into(), category: "sensitive-file".into() },
SourceDef { id: "python-chrome-login".into(), pattern: "Login Data".into(), category: "sensitive-file".into() },
SourceDef { id: "python-urlopen".into(), pattern: "urlopen".into(), category: "network-input".into() },
SourceDef { id: "python-requests-get".into(), pattern: "requests.get".into(), category: "network-input".into() },
SourceDef { id: "python-requests-post".into(), pattern: "requests.post".into(), category: "network-input".into() },
SourceDef { id: "python-httpx-get".into(), pattern: "httpx.get".into(), category: "network-input".into() },
SourceDef { id: "python-socket-recv".into(), pattern: ".recv".into(), category: "network-input".into() },
SourceDef { id: "python-socket-recvfrom".into(), pattern: ".recvfrom".into(), category: "network-input".into() },
SourceDef { id: "python-response-read".into(), pattern: "response.read".into(), category: "network-input".into() },
SourceDef { id: "python-resp-read".into(), pattern: "resp.read".into(), category: "network-input".into() },
SourceDef { id: "python-pickle-loads".into(), pattern: "pickle.loads".into(), category: "buffer".into() },
SourceDef { id: "python-marshal-loads".into(), pattern: "marshal.loads".into(), category: "buffer".into() },
SourceDef { id: "python-yaml-load".into(), pattern: "yaml.load".into(), category: "buffer".into() },
SourceDef { id: "python-yaml-unsafe-load".into(), pattern: "yaml.unsafe_load".into(), category: "buffer".into() },
SourceDef { id: "python-jsonpickle-decode".into(), pattern: "jsonpickle.decode".into(), category: "buffer".into() },
SourceDef { id: "python-dill-loads".into(), pattern: "dill.loads".into(), category: "buffer".into() },
SourceDef { id: "python-base64-decode".into(), pattern: "base64.b64decode".into(), category: "buffer".into() },
SourceDef { id: "python-base64-decodebytes".into(), pattern: "base64.decodebytes".into(), category: "buffer".into() },
SourceDef { id: "python-curl".into(), pattern: "curl".into(), category: "shell".into() },
SourceDef { id: "python-wget".into(), pattern: "wget".into(), category: "shell".into() },
SourceDef { id: "python-bin-sh".into(), pattern: "/bin/sh".into(), category: "shell".into() },
SourceDef { id: "python-bin-bash".into(), pattern: "/bin/bash".into(), category: "shell".into() },
SourceDef { id: "python-socket-af-inet".into(), pattern: "AF_INET".into(), category: "network-input".into() },
],
sinks: vec![
SinkDef { id: "python-eval".into(), pattern: "eval".into(), category: "exec".into() },
SinkDef { id: "python-exec".into(), pattern: "exec".into(), category: "exec".into() },
SinkDef { id: "python-compile".into(), pattern: "compile".into(), category: "exec".into() },
SinkDef { id: "python-os-system".into(), pattern: "os.system".into(), category: "exec".into() },
SinkDef { id: "python-os-popen".into(), pattern: "os.popen".into(), category: "exec".into() },
SinkDef { id: "python-subprocess-run".into(), pattern: "subprocess.run".into(), category: "exec".into() },
SinkDef { id: "python-subprocess-call".into(), pattern: "subprocess.call".into(), category: "exec".into() },
SinkDef { id: "python-subprocess-check-output".into(), pattern: "subprocess.check_output".into(), category: "exec".into() },
SinkDef { id: "python-subprocess-popen".into(), pattern: "subprocess.Popen".into(), category: "exec".into() },
SinkDef { id: "python-requests-get".into(), pattern: "requests.get".into(), category: "network".into() },
SinkDef { id: "python-requests-post".into(), pattern: "requests.post".into(), category: "network".into() },
SinkDef { id: "python-requests-put".into(), pattern: "requests.put".into(), category: "network".into() },
SinkDef { id: "python-socket-connect".into(), pattern: "socket.connect".into(), category: "network".into() },
SinkDef { id: "python-socket-send".into(), pattern: "socket.send".into(), category: "network".into() },
SinkDef { id: "python-socket-sendall".into(), pattern: "socket.sendall".into(), category: "network".into() },
SinkDef { id: "python-socket-socket-send".into(), pattern: "socket.socket.send".into(), category: "network".into() },
SinkDef { id: "python-socket-socket-sendall".into(), pattern: "socket.socket.sendall".into(), category: "network".into() },
SinkDef { id: "python-socket-socket-connect".into(), pattern: "socket.socket.connect".into(), category: "network".into() },
SinkDef { id: "python-pty-spawn".into(), pattern: "pty.spawn".into(), category: "exec".into() },
SinkDef { id: "python-os-dup2".into(), pattern: "os.dup2".into(), category: "exec".into() },
SinkDef { id: "python-asyncio-create-subprocess-shell".into(), pattern: "asyncio.create_subprocess_shell".into(), category: "exec".into() },
SinkDef { id: "python-paramiko-sshclient-connect".into(), pattern: "paramiko.SSHClient.connect".into(), category: "network".into() },
SinkDef { id: "python-paramiko-sshclient-exec-command".into(), pattern: "paramiko.SSHClient.exec_command".into(), category: "exec".into() },
SinkDef { id: "python-urllib-urlopen".into(), pattern: "urllib.request.urlopen".into(), category: "network".into() },
SinkDef { id: "python-urllib-urlopen-module".into(), pattern: "urllib.request".into(), category: "network".into() },
SinkDef { id: "python-open-write".into(), pattern: "open.write".into(), category: "file".into() },
SinkDef { id: "python-pickle-loads".into(), pattern: "pickle.loads".into(), category: "exec".into() },
SinkDef { id: "python-marshal-loads".into(), pattern: "marshal.loads".into(), category: "exec".into() },
SinkDef { id: "python-torch-load".into(), pattern: "torch.load".into(), category: "exec".into() },
SinkDef { id: "python-numpy-load".into(), pattern: "numpy.load".into(), category: "exec".into() },
SinkDef { id: "python-joblib-load".into(), pattern: "joblib.load".into(), category: "exec".into() },
SinkDef { id: "python-onnx-load".into(), pattern: "onnx.load".into(), category: "exec".into() },
SinkDef { id: "python-urllib2-urlopen".into(), pattern: "urllib2.urlopen".into(), category: "network".into() },
SinkDef { id: "python-httplib-request".into(), pattern: "http.client.HTTPConnection".into(), category: "network".into() },
SinkDef { id: "python-socket-getaddrinfo".into(), pattern: "socket.getaddrinfo".into(), category: "network".into() },
SinkDef { id: "python-dns-resolver".into(), pattern: "dns.resolver.resolve".into(), category: "network".into() },
],
sanitizers: vec![
SanitizerDef { id: "python-int".into(), pattern: "int".into() },
SanitizerDef { id: "python-float".into(), pattern: "float".into() },
SanitizerDef { id: "python-str".into(), pattern: "str".into() },
SanitizerDef { id: "python-bleach-clean".into(), pattern: "bleach.clean".into() },
SanitizerDef { id: "python-markupsafe-escape".into(), pattern: "markupsafe.escape".into() },
SanitizerDef { id: "python-shlex-quote".into(), pattern: "shlex.quote".into() },
SanitizerDef { id: "python-os-path-basename".into(), pattern: "os.path.basename".into() },
SanitizerDef { id: "python-re-compile".into(), pattern: "re.compile".into() },
],
}
}
pub(super) fn apply_labels(graph: &mut TaintGraph, label_set: &LabelSet) {
for id in 0..graph.node_count() as u32 {
let Some(node) = graph.node(id) else {
continue;
};
let label = label_node(label_set, &node.name)
.or_else(|| node.alias.as_deref().and_then(|alias| label_node(label_set, alias)));
if let Some(label) = label {
if let Some(node_mut) = graph.node_mut(id) {
node_mut.label = Some(label);
}
}
}
}