CINXE.COM
CERN Computer Security Information
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="/style.css" type="text/css" /> <script type="text/javascript" src="/jquery.min.js"></script> <title>CERN Computer Security Information</title> <script type="text/javascript"> $(document).ready(function(){ // Menu highlight var path = location.pathname.split("/"); if ( path ) { $('#main_menu a[href*="' + path[1] + '"][class!="noselect"]').addClass('selected'); // path[3] = /security/<xxxxx>/ $('#sidebar ul.sidemenu li[class!="noselect"]:has(a[href$="' + path.reverse()[0] + '"])').addClass('selected'); } // Add icon to external links $('a[id!=logo-img]').filter(function() { return this.hostname && this.hostname !== location.hostname; }).after(' <img src="/images/external_link.png" alt="external link" title="external link"/>'); }); </script> </head> <body> <div id="wrap"> <div id="top-bg"></div> <!--header --> <div id="header"> <div id="logo-text"> <a id="logo-img" href="https://home.cern/"><img src="/images/CERNLogo2.png" width="59" height="59" style="margin: 10px" alt="CERN Logo"/></a><div id="logo-text-big"><a href="/home/en/index.shtml" title="">CERN Computer Security</a></div> </div> <div id="header-logo"><a href="/services/en/emergency.shtml"><img width=335 src="/images/emergency.png" alt="Computer Emergencies"/></a></div> </div> <!--header ends--> <div id="header-photo"></div> <!-- navigation starts--> <div id="nav"> <ul id="main_menu"> <li><a class="noselect" href="/home/fr/index.shtml"><img src="/images/fr.png" alt="FR"/></a></li> <li><a href="/home/en/index.shtml">Home</a></li> <li><a href="/rules/en/index.shtml">Computing Rules</a></li> <li><a href="/recommendations/en/index.shtml">Recommendations</a></li> <li><a href="/training/en/index.shtml">Training</a></li> <li><a href="/services/en/index.shtml">Services</a></li> <li><a class="secured" href="/reports/en/index.shtml">Reports & Presentations</a></li> </ul> </div> <!-- navigation ends--> <!-- content-wrap starts --> <div id="content-wrap"> <div id="main"> <h2>Security Checklist for Software Developers</h2> <p>Security should be foreseen as part of the system from the very beginning, not added as a layer at the end. The latter solution produces insecure code (tricky patches instead of neat solutions), may limit functionality and will cost much more (in time/money).</p> <p>Here are some hints and tips for various phases of the software development lifecycle. This list certainly doesn't contain all pieces of advice that software engineers should follow. It just includes the most important ones - those which are definitely worth keeping in mind when designing and developing almost any kind of software with any programming language!</p> <h4>General</h4> <ul> <li>Think of the security implications of what your code does;</li> <li>Read and follow guidelines for your programming language and software type;</li> <li>Reuse trusted code (libraries, modules etc.);</li> <li>Write good-quality, readable and maintainable code (bad code won't ever be secure).</li> </ul> <h4>Architecture:</h4> <ul> <li><b>Modularity</b>: Divide the program into semi-independent parts (small, well-defined interfaces to each module/function);</li> <li><b>Isolation</b>: Each part should work correctly even if others fail (return wrong results, send requests with invalid arguments);</li> <li><b>Defense in depth:</b> Build multiple layers of defense instead of trusting just one protection mechanism. For example: validate user input data at entry point, and check again all values that are passed to sensitive parts of the code (like file handling etc.);</li> <li><b>Simplicity</b>: Complex solutions are much more likely to be insecure.</li> </ul> <h4>Design</h4> <ul> <li>Make <b>security-sensitive </b>parts of your code <b>small;</b></li> <li><b>Least privilege principle</b>: Don't require more privileges than you need. For example: run your code as the least privileged user necessary (don't run it as root, nor with SUID flag). Make sure that the account on which you will run your code has only the file access and execute privileges that your code really needs. Don't connect to a database with admin privileges from your software;</li> <li>Choose <b>safe defaults</b>: For example, a random password that users are likely to change rather than a standard default passwords that many won't bother to change;</li> <li><b>Deny by default</b>: For example, when validating user input accept only characters that you expect rather than trying to block known "bad" characters;</li> <li><b>Limit resource consumption</b>, to limit the likelihood or impact of a Denial of Service attack;</li> <li><b>Fail securely</b>: For example, if there is a runtime error when checking user's access rights, assume she has none;</li> <li>In distributed or Web applications <b>don't trust the client</b>: Don't expect it to validate user input, perform security checks or authenticate users - it all has to be done (again) on the server side; remember that HTTP response header fields (cookies, user-agent, referrer etc.) and HTTP query string values (from hidden fields or explicit links) may be forged/manipulated;</li> <li>Cryptography: <b>Use trusted, public algorithms, protocols and products</b>. Do not invent your own cryptographic algorithms or protocols, nor implement existing ones - reuse trusted code.</li> </ul> <h4>Coding</h4> <ul> <li><b>Don't trust input data</b>: Data coming from potentially malicious users is the single most common reason of security-related incidents (buffer overflow, SQL injection, Cross Site Scripting (XSS), code inside data etc.). Input data includes command-line arguments, configuration files (if accessible by not-trusted users), environment variables, cookies and POST/GET arguments etc;</li> <li><b>Validate all input data</b>: Consider all input dangerous until proven valid, deny by default if not sure, validate at different levels, for example at input data entry point and before really using that data;</li> <li><b>Don't make any assumptions about the environment</b>: make sure your code doesn't break with modified/malicious PATH, CLASSPATH and others environment variables, current directory, @INC Perl variable, umask, signals, open file descriptors etc;</li> <li><b>Beware of race condition</b>: Can your code run parallel? what if someone executes two instances of your program at the same time, or changes environment in the middle of its execution?</li> <li><b>Deal with errors and exceptions</b>: Don't assume that everything will work (especially file operations, system and network calls), catch exceptions, check result codes; don't display internal error messages, failing SQL query, stack trace etc;</li> <li><b>Fail gracefully</b>: If there is an unexpected error that you can't recover from, then log details, alert the administrator, clean the system (delete temporary files, clear memory) and inform the user;</li> <li><b>Protect passwords and secret information</b>: don't hard-code passwords (it's hard to change them and easy to disclose), use external files instead (possibly encrypted) or already existing credentials (like certificates), or simply ask the user for the password;</li> <li><b>Be careful when handling files</b>: If you want to create it, report an error if it already exists; when you create it, set file permissions; if you open a file to read data, don't ask for write access; check if the file you open is not a link with the lstat() function (before and after opening the file); use absolute pathnames (for both commands and files); be extra careful when the filename (or part of it) comes from a user;</li> <li><b>Temporary files</b>: Avoid them whenever possible. Pipes are a safer and more efficient way of communicating information between processes. If you really need remporary files, don't fall for the symbolic link attack (someone guesses the name of your temporary file, and creates a link from it to another file e.g. /bin/bash, that your program overwrites). Temporary files must have unique names that are hard to guess! (use tmpfile() for C/C++, mktemp shell command etc.);</li> <li><b>Be careful with shell calls, eval functions etc.</b>: Such functions evaluate the string argument as code and interpret it, or run it on the shell. If an attacker managed to inject malicious input to that argument, you're executing his code.</li> </ul> <h4>After the Implementation</h4> <ul> <li><b>Review your code</b> and let others review it;</li> <li><b>When a (security) bug is found, search for similar ones</b>;</li> <li><b>Use tools specific to your programming language:</b> Bounds checkers, memory testers, bug finders etc;</li> <li><b>Turn on compiler / interpreter warnings</b> and read them (perl -w, gcc -Wall);</li> <li><b>Disable debugging information</b> (strip command, javac -g:none, etc.).</li> </ul> </div> <!-- SIDEBAR --> <!-- sidebar menu starts --> <div id="sidebar"> <h3>For All Users<br/> (Experts or Not)</h3> <ul class="sidemenu"> <li><a href="/recommendations/en/good_practises.shtml">Seven easy good practises</a></li> <li><a href="/recommendations/en/how_to_secure_your_pc.shtml">How to secure your PC or Mac</a></li> <li><a href="/recommendations/en/passwords.shtml">Passwords & toothbrushes</a></li> <li><a href="/recommendations/en/2FA.shtml">Starting with multi-factor authentication</a></li> <li><a href="/recommendations/en/bad_mails.shtml">Bad mails for you:<br/>"Phishing", "SPAM" & fraud</a></li> <li><a href="/recommendations/en/malicious_email.shtml">How to identify malicious e-mails and attachments</a></li> <li><a href="/recommendations/en/how_to_remove_malicious_browser_notifications.shtml">How to remove malicious browser notifications</a></li> <li><a href="/recommendations/en/working_remotely.shtml">Working remotely</a></li> <li><a href="/recommendations/en/connecting_to_cern.shtml">Connecting to CERN</a></li> <li><a href="/recommendations/en/ssh.shtml">Connecting using SSH</a></li> </ul> <h3>For Software Developers</h3> <ul class="sidemenu"> <li>Good programming in <a href="/recommendations/en/program_c.shtml">C/C++</a>, <a href="/recommendations/en/program_java.shtml">Java</a>, <a href="/recommendations/en/program_perl.shtml">Perl</a>, <a href="/recommendations/en/program_php.shtml">PHP</a>, and <a href="/recommendations/en/program_python.shtml">Python</a></li> <li><a href="/recommendations/en/password_alternatives.shtml">How to keep secrets secret<br/> (alternatives to passwords)</a></li> <li><a href="/recommendations/en/checklist_for_coders.shtml">Security checklist</a></li> <li><a href="https://gitlab.docs.cern.ch/docs/Secure%20your%20application/">GitLab CI Security Tools</a></li> <li><a href="/recommendations/en/web_applications.shtml">Securing Web applications</a></li> <li><a href="/recommendations/en/code_tools.shtml">Static code analysis tools</a></li> <li><a href="/recommendations/en/more_on_software.shtml">Further reading</a></li> </ul> <h3>For System Owners</h3> <ul class="sidemenu"> <li><a href="/recommendations/en/rootkits.shtml">Checking for rootkits</a></li> <li><a href="https://twiki.cern.ch/twiki/bin/viewauth/CNIC/WebHome">Securing Control Systems (CNIC)</a></li> <li><a href="/recommendations/en/containers.shtml">Securing Containers & Pods</a></li> <li><a href="/rules/en/baselines.shtml">Security baselines</a></li> <li><a href="http://linux.web.cern.ch/linux/docs/linux_exploit_faq.shtml"> The CERN Linux vulnerability FAQ</a></li> </ul> </div> <!-- sidebar menu ends --> <!-- content-wrap ends--> </div> <!-- footer starts --> <div id="footer-wrap"> <div id="footer-bottom"> © Copyright 2024<strong> <a href="https://cern.ch/security">CERN Computer Security Office</a></strong> <table> <tr> <td id="footer-info-left"> e-mail: <a href="mailto:Computer.Security@cern.ch">Computer.Security@cern.ch</a><br/> Please use the following PGP key to encrypt your messages:<br/> ID: 0x954CE234B4C6ED84<br/> <a href="https://keys.openpgp.org/vks/v1/by-fingerprint/429D60460EBE8006B04CDF02954CE234B4C6ED84">429D 6046 0EBE 8006 B04C DF02 954C E234 B4C6 ED84</a> </td> <td id="footer-info-right"> Phone: +41 22 767 0500<br/> Please listen to the recorded instructions. </td> </tr> </table> </div> </div> <!-- footer ends--> </div> <!-- wrap ends here --> <!--img height=30px src="/home/en/CERNfooter_800.png"--> </body> </html>