";let n=document.getElementById("TableOfContents");n&&(n.innerHTML=e)}rerender(){this.rerenderFilterMenu(),this.rerenderPageContent(),this.populateRightNav(),this.runHooks("afterRerender")}rerenderPageContent(){let e={};Object.keys(this.ifFunctionsByRef).forEach(t=>{let s=this.ifFunctionsByRef[t],o=s.value,n=(0,h.reresolveFunctionNode)(s,{variables:this.selectedValsByTraitId});this.ifFunctionsByRef[t]=n,o!==n.value&&(e[t]=n.value)});let t=document.getElementsByClassName("cdoc__toggleable");for(let n=0;n{this.fitCustomizationMenuToScreen()})}addDropdownEventListeners(){let e=document.getElementsByClassName("cdoc-dropdown");for(let t=0;t{let t=e.target;for(;!t.classList.contains("cdoc-dropdown")&&t.parentElement;)t=t.parentElement;let n=t.classList.toggle("cdoc-dropdown__expanded");t.setAttribute("aria-expanded",n.toString())});document.addEventListener("keydown",e=>{if(e.key==="Enter"){let t=e.target;t.classList.contains("cdoc-filter__option")&&t.click()}}),document.addEventListener("click",t=>{for(let n=0;nthis.handleFilterSelectionChange(e));this.addDropdownEventListeners()}locateFilterSelectorEl(){let e=document.getElementById("cdoc-selector");return!!e&&(this.filterSelectorEl=e,!0)}applyFilterSelectionOverrides(){let s=Object.keys(this.selectedValsByTraitId),e=!1,t=this.browserStorage.getTraitVals();Object.keys(t).forEach(n=>{s.includes(n)&&this.selectedValsByTraitId[n]!==t[n]&&(this.selectedValsByTraitId[n]=t[n],e=!0)});let n=(0,j.getTraitValsFromUrl)({url:new URL(window.location.href),traitIds:s});return Object.keys(n).forEach(t=>{this.selectedValsByTraitId[t]!==n[t]&&(this.selectedValsByTraitId[t]=n[t],e=!0)}),e}updateEditButton(){let t=document.getElementsByClassName("toc-edit-btn")[0];if(!t)return;let e=t.getElementsByTagName("a")[0];e&&(e.href=e.href.replace(/\.md\/$/,".mdoc.md/"))}revealPage(){this.runHooks("beforeReveal"),this.filterSelectorEl&&(this.filterSelectorEl.style.position="sticky",this.filterSelectorEl.style.backgroundColor="white",this.filterSelectorEl.style.paddingTop="10px",this.filterSelectorEl.style.visibility="visible",this.filterSelectorEl.style.zIndex="1000");let e=document.getElementById("cdoc-content");e&&(e.style.visibility="visible"),this.runHooks("afterReveal")}rerenderFilterMenu(){if(!this.filterSelectorEl||!this.filtersManifest)throw new Error("Cannot rerender filter selector without filtersManifest and filterSelectorEl");let e=(0,l.resolveFilters)({filtersManifest:this.filtersManifest,valsByTraitId:this.selectedValsByTraitId});Object.keys(e).forEach(t=>{let n=e[t];this.selectedValsByTraitId[t]=n.currentValue});let t=(0,y.buildCustomizationMenuUi)(e);this.filterSelectorEl.innerHTML=t,this.fitCustomizationMenuToScreen(),this.addFilterSelectorEventListeners()}fitCustomizationMenuToScreen(){let e=document.getElementById(g);if(!e)return;let s=e.classList.contains(n),t=document.getElementById(v);if(!t)throw new Error("Dropdown menu not found");let o=document.getElementById(b);if(!o)throw new Error("Menu wrapper not found");let i=e.scrollWidth>o.clientWidth;!s&&i?(e.classList.add(n),t.classList.remove(n)):s&&!i&&(e.classList.remove(n),t.classList.add(n))}get cdocsState(){return{selectedValsByTraitId:this.selectedValsByTraitId,ifFunctionsByRef:this.ifFunctionsByRef,filtersManifest:this.filtersManifest,browserStorage:this.browserStorage,filterSelectorEl:this.filterSelectorEl}}};e.ClientFiltersManager=r,t=r,s={value:void 0}}),y=e(e=>{Object.defineProperty(e,"__esModule",{value:!0});var t=j();window.clientFiltersManager=t.ClientFiltersManager.instance}),y()})()Unsanitized data is sent to popen, causing command injection
Cette page n'est pas encore disponible en français, sa traduction est en cours. Si vous avez des questions ou des retours sur notre projet de traduction actuel, n'hésitez pas à nous contacter.
This rule identifies potential OS Command Injection vulnerabilities. These occur when user-supplied data from a POST request’s JSON body, such as input from request.get_json() or data.get("<key>"), is passed directly to the os.popen() function without sanitization or validation. This vulnerability allows an attacker to craft a JSON payload containing malicious commands. The server then executes these commands with the privileges of the running application, which can lead to unauthorized server access, data breaches, or denial of service.
How to Remediate
To prevent OS Command Injection vulnerabilities when handling user input for shell commands:
Avoid os.popen() with user input. Prefer using the subprocess module. Pass commands and arguments as a list (for example, subprocess.run(["command", "arg1", "arg2"], shell=False)). This method avoids shell interpretation of the command string.
Sanitize input if direct shell execution is unavoidable. Use functions such as shlex.quote() for any part of the command that originates from user input.
Implement allowlisting. Permit only a predefined set of commands or command patterns. Map user input to these safe, fixed command strings.
Adhere to the principle of least privilege. Run the application with the minimum privileges necessary for its operation.
Non-Compliant Code Examples
importosfromflaskimportFlask,requestapp=Flask(__name__)@app.route("/")defindex():return"Flask app is running. Add your first vulnerability!"@app.route("/run",methods=["POST"])defrun_command():data=request.get_json()command=data.get("command")ifdataelseNoneifnotcommand:return"Missing 'command' in request body",400stream=os.popen(command)output=stream.read()returnf"<pre>{output}</pre>"if__name__=="__main__":app.run(host="0.0.0.0",port=80)
Compliant Code Examples
importosimportshlexfromflaskimportFlask,requestimportsubprocessapp=Flask(__name__)@app.route("/run_safe_shlex",methods=["POST"])defrun_command_safe_shlex():data=request.get_json()user_command=data.get("command")ifdataelseNoneifnotuser_command:return"Missing 'command' in request body",400# Sanitize using shlex.quote for commands meant for the shell# This is safer but still relies on os.popen, ideally move to subprocesssafe_arg=shlex.quote(user_command)# Example: using it as an argument to a fixed command like echostream=os.popen(f"echo {safe_arg}")# user_command is now an argumentoutput=stream.read()returnf"<pre>{output}</pre>"@app.route("/run_safe_whitelist",methods=["POST"])defrun_command_safe_whitelist():data=request.get_json()action=data.get("action")ifdataelseNoneifnotaction:return"Missing 'action' in request body",400actual_command=""ifaction=="list_users":actual_command="whoami"# Fixed, safe commandelifaction=="show_date":actual_command="date"# Fixed, safe commandelse:return"Invalid action",400stream=os.popen(actual_command)# Executes a whitelisted, fixed commandoutput=stream.read()returnf"<pre>{output}</pre>"@app.route("/run_safe_subprocess",methods=["POST"])defrun_command_safe_subprocess():data=request.get_json()command_parts=data.get("command_array")ifdataelseNone# Expecting ["ls", "-l", "/tmp"]ifnotcommand_partsornotisinstance(command_parts,list):return"Missing 'command_array' (list) in request body",400# Using subprocess with a list of arguments and shell=False is safesttry:# Whitelist allowed executableifcommand_parts[0]notin["ls","echo","whoami","date"]:return"Command not allowed",400result=subprocess.run(command_parts,capture_output=True,text=True,check=True,shell=False)returnf"<pre>{result.stdout}</pre>"exceptsubprocess.CalledProcessErrorase:returnf"Error: {e.stderr}",500exceptFileNotFoundError:returnf"Command not found: {command_parts[0]}",400# This should not be flagged as command_from_config is not from request.get_json()@app.route("/run_config_command",methods=["POST"])defrun_config_command():# data = request.get_json() # Input not used for commandcommand_from_config="ls -l /etc"stream=os.popen(command_from_config)output=stream.read()returnf"<pre>{output}</pre>"
Seamless integrations. Try Datadog Code Security
Datadog Code Security
Try this rule and analyze your code with Datadog Code Security
How to use this rule
1
2
rulesets:- python-flask # Rules to enforce Python flask.
Create a static-analysis.datadog.yml with the content above at the root of your repository
Use our free IDE Plugins or add Code Security scans to your CI pipelines