Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Secure software starts with deliberate design, not a last-minute scan. The title “10 Steps to Secure Software” has been used for two different lists: this guide follows Jim Bird’s developer-focused checklist, published by DZone on December 14, 2015, and treats Gary McGraw’s separate principles reproduced in a Progress Software workshop as a complementary lens—not as a merged or current canonical standard. The implementation principles below remain useful, but Bird’s product, library, and version-specific references are historical; confirm present-day choices against current official guidance.

1. Prevent SQL injection with parameterized queries

When a database query uses user-supplied values, keep the query structure separate from those values. Parameterized queries let the database treat input as data rather than executable SQL. Do not build a query by concatenating raw input into a command.

This is a targeted defense: it addresses SQL injection, while other interpreters and output contexts need their own protections.

2. Encode data for the interpreter or output context

Data that is safe in one context may be unsafe in another. Encode values for the specific interpreter or output context before passing them on—for example, HTML output requires context-appropriate encoding. Encoding is not a substitute for input validation, and generic escaping should not be assumed to work everywhere.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Validate input before using or storing it

Treat data from outside the application as untrusted. Validate it against the format, range, and business rules expected at that point, before using it or persisting it. Validation helps reject malformed or unexpected values; it does not replace parameterized queries or context-specific output encoding.

4. Deny access by default and authorize on the server

Make authorization decisions on the server, where clients cannot simply alter a local control or request. Start from denial and grant access only when the user or service is explicitly permitted to perform the requested action. Centralize authorization logic where practical so that access rules are consistent and reviewable.

5. Manage identity and sessions deliberately

Use established identity and session-management mechanisms rather than inventing an authentication or session scheme. Where available and appropriate, use multifactor authentication (MFA). Define how sessions are created, validated, and ended, and ensure that server-side checks—not a client’s claims alone—establish identity and permissions.

6. Protect sensitive data throughout its lifecycle

Consider sensitive information wherever it exists: in storage, during transmission, while being processed, in backups, and in recovery paths. Apply access controls, auditing, and encryption where appropriate to the data and its exposure. Privacy protection is not complete if data is secured in the primary database but exposed through another copy or workflow.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

7. Log for audit and investigation without exposing secrets

Logging can support auditing, detection, and forensic investigation, but logs can also become a sensitive data store. Decide what events are necessary to understand security-relevant activity, restrict access to logs, and avoid recording sensitive information unnecessarily. Keep logs useful for investigation without turning them into an alternate path to private data.

8. Use established framework security features and libraries

Prefer security capabilities maintained by established frameworks and libraries over custom security code. Custom implementations can be difficult to review and maintain; using a framework feature still requires configuring it correctly and keeping the framework and dependencies maintained.

9. Handle errors without leaking information or failing unpredictably

Errors should not disclose sensitive details to users or create inconsistent, insecure behavior. Return appropriately limited messages to clients, while retaining enough controlled diagnostic information for operators to investigate. Make failure behavior predictable and ensure that recovery paths do not bypass normal security checks.

10. Make security review and testing part of development

Build security review and automated tests into ordinary development and CI/CD workflows rather than leaving them to a final release gate. Review changes that affect trust boundaries, authorization, data handling, and failure behavior. Tests should exercise security-relevant cases as well as expected success paths.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Extend the checklist to the software supply chain

Application controls do not cover every way software can be compromised. Tor Beer’s Legit Security article, published August 2, 2022 and updated February 13, 2026, describes the supply chain as including source control, build and test systems, compilers, dependencies, cloud services, and third-party services. This is a vendor-authored practical perspective, not a neutral standard or a requirement to buy a particular product.

  • Map the pipeline: identify the components, services, and dependencies involved in producing and delivering software.
  • Protect security controls: avoid unreviewed or unauthorized ways to bypass pipeline checks.
  • Automate relevant checks: use static application security testing (SAST) for source code and software composition analysis (SCA) for dependencies where they fit the project.
  • Monitor third parties: track relevant suppliers and the components or services on which the software relies.
  • Prepare for incidents: define response responsibilities and a plan for addressing a compromised component or pipeline.
  • Test running software: consider dynamic application security testing (DAST), including API testing, as part of runtime assessment.

Choose tools by fit rather than by category label alone. Compare supported languages and ecosystems, code and dependency coverage, CI/CD integration, the actionability of findings, false-positive burden, maintenance needs, and total cost. The sources cited here do not establish a single best product.

A broader lens: ten security principles

A Progress Software workshop PDF marked 2013 reproduces a separate set of principles attributed to Gary McGraw. It states, “Applications must have security designed in.” The document supports attributing that sentence to the workshop; it does not establish it as a verbatim quotation spoken by McGraw.

  1. Identify and secure the weakest link.
  2. Practice defense in depth.
  3. Be reluctant to trust.
  4. Remember that hiding secrets is hard.
  5. Follow the principle of least privilege.
  6. Fail and recover securely.
  7. Compartmentalize.
  8. Keep it simple.
  9. Keep trust to yourself.
  10. Assume nothing.

These principles complement Bird’s implementation checklist: they encourage teams to look for weak links, limit privileges, separate components, and plan for secure failure and recovery. Security work also needs to be revisited as the application, its dependencies, and the threats it faces change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sources

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.