<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joe Kutner</title>
    <description>The latest articles on DEV Community by Joe Kutner (@codefinger).</description>
    <link>https://dev.to/codefinger</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F139100%2Fdf000df3-e8ab-4b67-8f40-c6d0018bcf17.jpg</url>
      <title>DEV Community: Joe Kutner</title>
      <link>https://dev.to/codefinger</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codefinger"/>
    <language>en</language>
    <item>
      <title>Ground Control to Major TOML: Why Buildpacks Use a Most Peculiar Format</title>
      <dc:creator>Joe Kutner</dc:creator>
      <pubDate>Wed, 22 Jul 2020 15:08:01 +0000</pubDate>
      <link>https://dev.to/heroku/ground-control-to-major-toml-why-buildpacks-use-a-most-peculiar-format-5f99</link>
      <guid>https://dev.to/heroku/ground-control-to-major-toml-why-buildpacks-use-a-most-peculiar-format-5f99</guid>
      <description>&lt;p&gt;YAML files dominate configuration in the cloud native ecosystem. They’re used by Kuberentes, Helm, Tekton, and many other projects to define custom configuration and workflows. But YAML has its oddities, which is why the Cloud Native Buildpacks project chose TOML as its primary configuration format.&lt;/p&gt;

&lt;p&gt;TOML is a minimal configuration file format that's easy to read because of its simple semantics. You can learn more about TOML from the &lt;a href="https://toml.io/en/"&gt;official documentation&lt;/a&gt;, but a simple buildpack TOML file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;api&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2"&lt;/span&gt;

&lt;span class="nn"&gt;[buildpack]&lt;/span&gt;
&lt;span class="py"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"heroku/maven"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Maven"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike YAML, TOML doesn’t rely on significant whitespace with difficult to read indentation. TOML is designed to be human readable, which is why it favors simple structures. It’s also easy for machines to read and write; you can even append to a TOML file without reading it first, which makes it a great data interchange format. But data interchange and machine readability aren’t the main driver for using TOML in the Buildpacks project; it’s humans.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sJ6jnSsQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://heroku-blog-files.s3.amazonaws.com/posts/1595374389-major-toml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sJ6jnSsQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://heroku-blog-files.s3.amazonaws.com/posts/1595374389-major-toml.png" alt="Blog post illustration" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Put Your Helmet On
&lt;/h2&gt;

&lt;p&gt;The first time you use Buildpacks, you probably won’t need to write a TOML file. Buildpacks are designed to get out of your way, and disappear into the details. That’s why there’s no need for large configuration files like a &lt;a href="https://helm.sh/docs/chart_template_guide/values_files/"&gt;Helm values.yaml&lt;/a&gt; or a &lt;a href="https://kubernetes.io/docs/concepts/configuration/"&gt;Kubernetes pod configuration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Buildpacks favor convention over configuration, and therefore don’t require complex customizations to tweak the inner workings of its tooling. Instead, Buildpacks detect what to do based on the contents of an application, which means configuration is usually limited to simple properties that are defined by a human.&lt;/p&gt;

&lt;p&gt;Buildpacks also favor infrastructure as &lt;em&gt;imperative&lt;/em&gt; code (rather than &lt;em&gt;declarative&lt;/em&gt;). Buildpacks themselves are functions that run against an application, and are best implemented in higher level languages, which can use libraries and testing.&lt;/p&gt;

&lt;p&gt;All of these properties lend to a simple configuration format and schema that doesn’t define complex structures. But that doesn’t mean the decision to use TOML was simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can You Hear Me, Major TOML?
&lt;/h2&gt;

&lt;p&gt;There are many other formats the Buildpacks project could have used besides YAML or TOML, and the Buildpacks core team considered all of these in the early days of the project.&lt;/p&gt;

&lt;p&gt;JSON has simple syntax and semantics that are great for data interchange, but it doesn’t make a great human-readable format; in part because it doesn’t allow for comments. Buildpacks use JSON for machine readable config, like the OCI image metadata. But it shouldn’t be used for anything a human writes.&lt;/p&gt;

&lt;p&gt;XML has incredibly powerful properties including schema validation, transformation tools, and rich semantics. It’s great for markup (like HTML) but it's much too heavy of a format for what Buildpacks require.&lt;/p&gt;

&lt;p&gt;In the end, the Buildpacks project was comfortable choosing TOML because there was solid prior art (even though the format is somewhat obscure). In the cloud native ecosystem, the &lt;a href="https://containerd.io/"&gt;containerd&lt;/a&gt; project uses TOML. Additionally, many language ecosystem tools like &lt;a href="http://doc.crates.io/"&gt;Cargo&lt;/a&gt; (for Rust) and &lt;a href="https://python-poetry.org/"&gt;Poetry&lt;/a&gt; (for Python) use TOML to configure application dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commencing Countdown, Engines On
&lt;/h2&gt;

&lt;p&gt;The main disadvantage of TOML is its ubiquity. Tools that parse and query TOML files (something comparable to &lt;code&gt;jq&lt;/code&gt;) aren’t readily available, and the format can still be jarring to new users even though it’s fairly simple.&lt;/p&gt;

&lt;p&gt;Every trend has to start somewhere, and the Cloud Native Buildpacks project is happy to be one of the projects stepping through the door.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>buildpacks</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>Samurai Duke and the Legend of OpenJDK</title>
      <dc:creator>Joe Kutner</dc:creator>
      <pubDate>Wed, 10 Jul 2019 19:05:06 +0000</pubDate>
      <link>https://dev.to/heroku/samurai-duke-and-the-legend-of-openjdk-418</link>
      <guid>https://dev.to/heroku/samurai-duke-and-the-legend-of-openjdk-418</guid>
      <description>&lt;p&gt;What is Duke? No one knows his species or genus. People say he’s a Java Bean or a Software Agent, but all we know for sure is that he reminds us of the &lt;a href="https://blog.heroku.com/the_next_twenty_years_of_java_where_we_ve_been_and_where_we_re_going" rel="noopener noreferrer"&gt;more than twenty-year legacy of the Java language&lt;/a&gt; and its community. The Java community has such an affinity for Duke that designers have created surfing Duke, astronaut Duke, rockstar Duke, macramé Duke, and of course Heroku’s Samurai Duke.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fheroku-blog-files.s3.amazonaws.com%2Fposts%2F1562626183-heroku-blog-duke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fheroku-blog-files.s3.amazonaws.com%2Fposts%2F1562626183-heroku-blog-duke.png" alt="Java Duke"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But how can all of these Duke variants exist without violating copyright or trademark laws? After all, Duke represents the language at the middle of one of the &lt;a href="https://www.eff.org/cases/oracle-v-google" rel="noopener noreferrer"&gt;fiercest copyright battles in the history of software&lt;/a&gt;. The answer, it turns out, can teach us a great deal about how to nurture an open source community.&lt;/p&gt;

&lt;p&gt;Java’s history is filled with ups and downs, rights and wrongs, plaintiffs and defendants, and a whole lotta XML. And just as those who don’t read history are doomed to repeat it, learning about Java’s past might help you grow the communities and products you contribute to--even if you’re only reading about a mascot.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Origin Story
&lt;/h2&gt;

&lt;p&gt;Duke was created in the earliest days of Java by Joe Palrang, an artist who helped animate films including Shrek and Over the Hedge. At the time, Duke was the property of Sun Microsystems and was as proprietary as Java itself. But Duke was poised to lead Java’s charge into a brave new world.&lt;/p&gt;

&lt;p&gt;In 2006, Duke was open-sourced under a BSD license, which coincided with the release of the Java HotSpot virtual machine and compiler under the GNU GPL license. This was the first subset of a truly open source Java, and Sun Microsystems promised that the rest of the JDK would be released under the GPL within the next year. Duke, already the mascot for Java, became the herald of a new future where Java could be freely distributed--just like Duke could be freely customized by designers.&lt;/p&gt;

&lt;p&gt;A completely free and open source Java may seem inevitable today, but fifteen years ago there was no certainty in the matter. Sun was struggling to make money despite producing some of the most innovative technologies in the industry, and giving their most successful product away for free seemed unrealistic.&lt;/p&gt;

&lt;p&gt;As the decade came to a close, Sun was acquired by Oracle and the first Java release under new ownership, JDK 7, was also the first in which the reference implementation was free and open source under the GNU GPL License. Today, there are multiple &lt;a href="http://openjdk.java.net/" rel="noopener noreferrer"&gt;OpenJDK&lt;/a&gt; distributions and the open Java ecosystem is thriving--along with Duke.&lt;/p&gt;

&lt;p&gt;That’s why Heroku, who has always supported a freely distributable version of OpenJDK, knew exactly where to look when it needed a logo for its Java product.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fheroku-blog-files.s3.amazonaws.com%2Fposts%2F1562110142-heroku-blog-samurai-duke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fheroku-blog-files.s3.amazonaws.com%2Fposts%2F1562110142-heroku-blog-samurai-duke.png" alt="Heroku's Samurai Duke"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Way of Samurai Duke
&lt;/h2&gt;

&lt;p&gt;Actually, Duke was not Heroku’s first choice for a logo (sorry Duke). The story of how Duke became a Samurai is shrouded in mystery, intrigue, and lawyers. &lt;/p&gt;

&lt;p&gt;The famous Java coffee cup with steam rising from it (which we are not allowed to show here) was the first logo Heroku tried. But our lawyers informed us that we were violating Oracle’s license on that image.&lt;/p&gt;

&lt;p&gt;For once, lawyers did us a favor. By taking the coffee cup option away, they forced us to think harder about what Heroku Java should look like.&lt;/p&gt;

&lt;p&gt;We thought of Duke, but a plain-old naked Duke just wasn’t exciting enough for Heroku’s standards. We decided to dress him up and in classic Heroku style, so we gave him a Samurai outfit. Initially, Samurai Duke had a samurai sword in his belt, but our corporate team informed us that it was too violent and had to be removed. The end result is a cute, non-violent Samurai Duke, whom we love.&lt;/p&gt;

&lt;p&gt;Heroku has long been the ally of a free and open Java and the OpenJDK project. Samurai Duke is our metaphorical protector of that freedom. The next time you see Heroku at a conference, be sure to say hello and ask for one of our Samurai Duke stickers. Or grab a copy of our &lt;a href="https://www.heroku.com/art/duke" rel="noopener noreferrer"&gt;Samurai Duke wallpaper&lt;/a&gt;. You’ll be helping us celebrate Java and open source.&lt;/p&gt;

</description>
      <category>java</category>
      <category>duke</category>
      <category>oracle</category>
      <category>sun</category>
    </item>
    <item>
      <title>Ten Ways to Secure your Applications</title>
      <dc:creator>Joe Kutner</dc:creator>
      <pubDate>Thu, 21 Feb 2019 17:49:29 +0000</pubDate>
      <link>https://dev.to/heroku/ten-ways-to-secure-your-applications-48df</link>
      <guid>https://dev.to/heroku/ten-ways-to-secure-your-applications-48df</guid>
      <description>&lt;p&gt;&lt;em&gt;This blog post is adapted from a talk given by Joe Kutner at Devoxx 2018 titled "&lt;a href="https://www.youtube.com/watch?v=0jFAGmEVT7Y" rel="noopener noreferrer"&gt;10 Mistakes Hackers Want You to Make&lt;/a&gt;."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Building self-defending applications and services is no longer aspirational--it’s required. Applying security patches, handling passwords correctly, sanitizing inputs, and properly encoding output is now table stakes. Our attackers keep getting better, and so must we.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll take a look at several commonly overlooked ways to secure your web apps. Many of the examples provided will be specific to &lt;a href="https://openjdk.java.net/" rel="noopener noreferrer"&gt;Java&lt;/a&gt;, but any modern programming language will have equivalent tactics. Please feel free to share methods for other languages in the comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Ensure dependencies are up-to-date
&lt;/h2&gt;

&lt;p&gt;Every year, &lt;a href="https://www.owasp.org/index.php/Main_Page" rel="noopener noreferrer"&gt;OWASP&lt;/a&gt;, a group of security experts and researchers, publishes a list of the common application security risks to watch out for. One of the more common issues they've found is &lt;a href="https://www.owasp.org/index.php/Top_10-2017_A9-Using_Components_with_Known_Vulnerabilities" rel="noopener noreferrer"&gt;the use of dependencies with known vulnerabilities&lt;/a&gt;. Once a known &lt;a href="https://cve.mitre.org/" rel="noopener noreferrer"&gt;CVE&lt;/a&gt; is published, many open source maintainers and contributors make a concentrated effort to released patched updates to popular frameworks and libraries. But one report found that &lt;a href="https://www.itgovernance.co.uk/blog/more-than-70-of-cyber-attacks-exploit-patchable-vulnerabilities" rel="noopener noreferrer"&gt;more than 70% of exploited applications are due to outdated dependencies&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To ensure that your projects are relying on the latest and greatest packages, and &lt;strong&gt;automating your dependency management&lt;/strong&gt; is recommended.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://maven.apache.org/" rel="noopener noreferrer"&gt;Maven&lt;/a&gt;, you can use the &lt;a href="https://www.mojohaus.org/versions-maven-plugin/" rel="noopener noreferrer"&gt;Maven Versions Plugin&lt;/a&gt;, which automatically updates your &lt;code&gt;pom.xml&lt;/code&gt; to use the newest packages. In &lt;a href="https://www.ruby-lang.org/en/" rel="noopener noreferrer"&gt;Ruby&lt;/a&gt;, the &lt;code&gt;bundle update&lt;/code&gt; command does something similar. You could incorporate these tools into your CI/CD process, and have a test outright fail if a dependency is outdated, thus forcing you to upgrade a package before your app can be deployed.&lt;/p&gt;

&lt;p&gt;A more proactive approach might be to incorporate a tool that automatically monitors your dependencies for you, such as &lt;a href="https://elements.heroku.com/addons/snyk" rel="noopener noreferrer"&gt;Snyk&lt;/a&gt;. Rather than running a check when code is modified (which could expose your app to a vulnerability for weeks or months, if it's infrequently updated), Snyk monitors your dependencies and compares them with &lt;a href="https://snyk.io/vuln" rel="noopener noreferrer"&gt;a known list of vulnerabilities mapped to dependencies&lt;/a&gt;. If a problem is identified, they'll alert you with a report identifying which dependencies are outdated and which version contains a patched fix. Snyk is also free to try on Heroku.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Explicitly declare acceptable user payloads
&lt;/h2&gt;

&lt;p&gt;All too often, web applications will accept nearly anything a user submits through a form or an API. For example, a user may attempt to create an account with a password containing over a thousand characters. When numerous requests like this are sent, it is possible the server will &lt;a href="https://arstechnica.com/information-technology/2013/09/long-passwords-are-good-but-too-much-length-can-be-bad-for-security/" rel="noopener noreferrer"&gt;crash under the intense computation necessary&lt;/a&gt; to encrypt them.&lt;/p&gt;

&lt;p&gt;One way to mitigate attacks like this is by implementing database-level constraints. Columns should have a maximum size defined, or your data model should refuse to accept &lt;code&gt;NULL&lt;/code&gt; values. While placing these restrictions on the database is always a good idea, it can be considered too "low level," as certain attacks can be exploited fair earlier in the request cycle.&lt;/p&gt;

&lt;p&gt;If your application is exposed to the Internet, every vulnerability is just one &lt;code&gt;curl&lt;/code&gt; call away. &lt;a href="https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/" rel="noopener noreferrer"&gt;In one example with the Jackson data-binding library&lt;/a&gt;, a simple JSON payload was able to execute arbitrary code, once the request was received by the server.&lt;/p&gt;

&lt;p&gt;By &lt;strong&gt;providing an explicit list of expected inputs&lt;/strong&gt; , you can ensure that your application is only operating on data that it knows will be coming, and ignoring (or politely erroring) on everything else. If your application accepts JSON, perhaps as part of an API, implementing &lt;a href="https://json-schema.org/" rel="noopener noreferrer"&gt;JSON schemas&lt;/a&gt; are an excellent way to model acceptable requests. For example, if an endpoint takes two &lt;code&gt;string&lt;/code&gt; fields named &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt;, and one integer named &lt;code&gt;age&lt;/code&gt;, a JSON schema to validate user-provided requests might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The person's first name."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lastName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The person's last name."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Age in years which must be equal to or greater than zero."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"integer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"minimum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By stating the valid types, you can prevent unexpected issues from occurring if a user decides to send integers for &lt;code&gt;firstName&lt;/code&gt; or negative numbers for &lt;code&gt;age&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In addition to the request body, you should also check request headers and query parameters, which can be similarly exploitable.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Assert safe regular expressions
&lt;/h2&gt;

&lt;p&gt;Regular expressions are both a boon and curse for every developer. They can make pattern matching on strings an easy task, but a poorly crafted regular expression can also bring an application down.&lt;/p&gt;

&lt;p&gt;Consider a simple pattern like this one: &lt;code&gt;(a|aa)+&lt;/code&gt;. While it looks innocuous, the &lt;code&gt;|&lt;/code&gt; ("or") combined with the &lt;code&gt;+&lt;/code&gt; operator can take a catastrophically long time to match against a string such as &lt;code&gt;"aaaaaaaaaaaaaaaaaaaaaaaa!"&lt;/code&gt;. Malicious users could cause a denial-of-service attack on your system by submitting a particularly complicated (yet still technically "valid") text. (&lt;a href="https://medium.com/node-security/minimatch-redos-vulnerability-590da24e6d3c" rel="noopener noreferrer"&gt;A similar issue affected the Node.js community&lt;/a&gt; several years ago.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validating your regular expressions&lt;/strong&gt; will ensure that they are not susceptible to this type of &lt;a href="https://en.wikipedia.org/wiki/ReDoS#Malicious_regexes" rel="noopener noreferrer"&gt;ReDoS attack&lt;/a&gt;. One tool you can use is &lt;a href="https://github.com/jkutner/saferegex" rel="noopener noreferrer"&gt;saferegex&lt;/a&gt;, a command-line Java utility that will report on the likelihood of a regular expressions causing a problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ java -jar target/saferegex.jar "(a|aa)+"

Testing: (a|aa)+
More than 10000 samples found.
***
This expression is vulnerable.
Sample input: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Prevent abusive requests
&lt;/h2&gt;

&lt;p&gt;Building a popular application involves more than just adding desired features. Your site will also need to handle the amount of traffic it receives as it grows. Even if every part of your application is secure, bad actors who repeatedly hammer your servers could succeed in bringing them down.&lt;/p&gt;

&lt;p&gt;To ensure uptime for your users, you should &lt;strong&gt;throttle aggressive clients&lt;/strong&gt;. This can be done in a few different ways, like limiting requests by IP address or user agent.&lt;/p&gt;

&lt;p&gt;A better implementation would be to use a library that takes advantage of &lt;a href="https://en.wikipedia.org/wiki/Token_bucket#Algorithm" rel="noopener noreferrer"&gt;a token-bucket algorithm&lt;/a&gt;. &lt;a href="https://github.com/vladimir-bukhtoyarov/bucket4j" rel="noopener noreferrer"&gt;Bucket4j&lt;/a&gt; is one such library. Incoming requests are grouped by a variety of properties into individual "buckets," and those buckets can in turn be throttled or blacklisted entirely. By classifying which requests are acceptable and which aren't, you'll be able to better handle sudden bursts of traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Align your code to be secure-first
&lt;/h2&gt;

&lt;p&gt;Often, in the midst of a particularly frustrating bug, we may in our haste implement a solution pilfered from some corner of the Internet. While &lt;em&gt;finally&lt;/em&gt; solving a problem may come as a much-needed relief, it's always worth triple-checking that you haven't inadvertently introduced a security issue.&lt;/p&gt;

&lt;p&gt;A few years ago, &lt;a href="https://blog.acolyer.org/2018/06/27/secure-coding-practices-in-java-challenges-and-vulnerabilities" rel="noopener noreferrer"&gt;researchers found that a majority of acceptable answers on StackOverflow contained insecure flaws&lt;/a&gt;. &lt;strong&gt;Code that works does not mean that code is secure.&lt;/strong&gt; Even if a snippet works in the short-term, it's important to be absolutely certain that it is safe to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Store credentials outside your codebase
&lt;/h2&gt;

&lt;p&gt;We all know (hopefully!) that divulging your personal password can be a catastrophic mistake. In any sufficiently complicated application, there can be a dozen different tokens and passwords to manage: your database username and password, tokens to authenticate to New Relic, or DataDog, or Redis...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep your application's configuration separate from your code.&lt;/strong&gt; Even if your repository is private, embedding plaintext credentials is never a good idea. A disgruntled employee who shouldn't have access could steal the token to impersonate users. To ensure that your project is safe, you should be confident that, if the code became open source at any moment, none of your credentials would be compromised.&lt;/p&gt;

&lt;p&gt;Store your secrets in environment variables. A library like &lt;a href="https://github.com/cdimascio/java-dotenv" rel="noopener noreferrer"&gt;dotenv&lt;/a&gt; can seamlessly load and make use of these variables, provided they're accessible in a secure location. Another option is to use a product like &lt;a href="https://www.vaultproject.io/" rel="noopener noreferrer"&gt;Hashicorp Vault&lt;/a&gt;, which allows your application to manage secrets through a configurable CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Deny HTTP requests
&lt;/h2&gt;

&lt;p&gt;Unless you have a very specific use case, you should &lt;strong&gt;disable HTTP connections to your server&lt;/strong&gt;. An HTTPS connection ensures that data between the client and the server is encrypted, thus prohibiting person-in-the-middle snooping attacks. Most major browsers default to HTTPS connections by default, and services such as &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt; make it easier than ever to obtain an SSL certificate for your application.&lt;/p&gt;

&lt;p&gt;If you need to support HTTP locally or between a proxy and your web server, you can configure your server to only accepts clients whose &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto" rel="noopener noreferrer"&gt;&lt;code&gt;X-Forwarded-Proto&lt;/code&gt; request header&lt;/a&gt; is set to &lt;code&gt;https&lt;/code&gt;. Depending on your setup, this may also be configurable outside of your code via an NGINX or Apache configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Enable certificate checking
&lt;/h2&gt;

&lt;p&gt;Sometimes, your application might need to make a call to an external provider. Similar to the suggestion above, you should &lt;strong&gt;enable certificate checking for outgoing connections&lt;/strong&gt;. This ensures that communication to third-party APIs or services are also secured via HTTPS. Note that if a third-party website has a misconfigured certificate, it can cause errors when your application tries to connect. You might be tempted to just disable certificate checking to ensure that the application "just works," but this is a very insecure move that puts your users' data at risk.&lt;/p&gt;

&lt;p&gt;You can use a library like &lt;a href="https://github.com/heroku/env-keystore" rel="noopener noreferrer"&gt;EnvKeyStore&lt;/a&gt; to facilitate the storage of keys and certificates. Similar to dotenv, EnvKeyStore asks that you keep set a certificate PEM be to an environment variable. You can then use this PEM as the default checker for any outgoing client requests. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;KeyStore&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnvKeyStore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createWithRandomPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TRUSTED_CERT"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;keyStore&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;tmfAlgorithm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TrustManagerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDefaultAlgorithm&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;TrustManagerFactory&lt;/span&gt; &lt;span class="n"&gt;tmf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TrustManagerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmfAlgorithm&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;tmf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;SSLContext&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SSLContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TLS"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tmf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTrustManagers&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SecureRandom&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;HttpsURLConnection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDefaultSSLSocketFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSocketFactory&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;urlStr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://ssl.selfsignedwebsite.xyz"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="no"&gt;URL&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urlStr&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;HttpsURLConnection&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpsURLConnection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openConnection&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDoInput&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRequestMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Log and monitor suspicious behavior
&lt;/h2&gt;

&lt;p&gt;Many applications only log critical failures, like unexpected server errors. But even behavior we have accounted for can be used as an attack vector. In those cases, it's imperative to &lt;strong&gt;log any sensitive action&lt;/strong&gt;. An example of some behavior to log includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Successful and unsuccessful logins&lt;/li&gt;
&lt;li&gt;Password resets&lt;/li&gt;
&lt;li&gt;Changes to access levels&lt;/li&gt;
&lt;li&gt;Authorization failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many of these cases, a user who is repeatedly generating an error may be a sign of a malicious attacker attempting to take over an account.&lt;/p&gt;

&lt;p&gt;In order to separate these events from other errors, we recommend prefixing your log statements with phrases such as &lt;code&gt;SECURITY_SUCCESS&lt;/code&gt;, &lt;code&gt;SECURITY_FAILURE&lt;/code&gt;, and &lt;code&gt;SECURITY_AUDIT&lt;/code&gt;. This way, you can easily filter on specific categories of authorization failures, should the need arise. Keep in mind that sensitive information, such as session IDs or passwords, should not be logged, as they will be stored in plaintext.&lt;/p&gt;

&lt;p&gt;Another tactic to employ is to &lt;strong&gt;add an intrusion detection system&lt;/strong&gt;. OWASP has a project called &lt;a href="http://appsensor.org/" rel="noopener noreferrer"&gt;AppSensor&lt;/a&gt;, which provides a framework to detect and respond to potential attacks in an automated way. This works by adding an agent to your web application which sends events to your external AppSensor service. AppSensor will analyze those events, and, if it determines malicious behavior, AppSensor will respond back to the web app with a payload of information identifying what is going on. The application can then determine which action to take.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimage.slidesharecdn.com%2F10-mistakes-devoxx-181115073417%2F95%2F10-mistakes-hackers-want-you-to-make-87-638.jpg%3Fcb%3D1542267300" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimage.slidesharecdn.com%2F10-mistakes-devoxx-181115073417%2F95%2F10-mistakes-hackers-want-you-to-make-87-638.jpg%3Fcb%3D1542267300" alt="UML of AppSensor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take a look at &lt;a href="https://www.owasp.org/index.php/AppSensor_DetectionPoints" rel="noopener noreferrer"&gt;the list of AppSensor detection points&lt;/a&gt; to potentially identify where your application needs improved intrusion detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Limit your own access
&lt;/h2&gt;

&lt;p&gt;We all make mistakes. Although we ask users of our applications to behave with security in mind, &lt;strong&gt;we also need to practice good security hygiene&lt;/strong&gt;. Some common sense actions that everyone should take include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using two-factor authentication wherever possible&lt;/li&gt;
&lt;li&gt;Locking your computer screen any time you're not at your workstation&lt;/li&gt;
&lt;li&gt;Implementing unique passwords across accounts and services, and using a password manager&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Security is hard, not because it's difficult to implement, but because it's difficult to identify &lt;em&gt;how&lt;/em&gt; to be secure. When writing code it's far easier to achieve the intended functionality but much harder to conceive the unintended functionality, which is where your security issues will arise. In addition, there are many different kinds of security that comprise a healthy security posture: network security, platform security, physical security, and so on.&lt;/p&gt;

&lt;p&gt;The ten ways you just learned to protect yourself are good starting points to ensure that your application security is top-notch. If you want to continue learning about web application security, you can check out &lt;a href="https://www.owasp.org/index.php/Getting_Started" rel="noopener noreferrer"&gt;the OWASP Getting Started&lt;/a&gt; guide for more information.&lt;/p&gt;

&lt;p&gt;Stay safe, and again share any security tips you have in the comments—for Java or any other language!&lt;/p&gt;

</description>
      <category>security</category>
      <category>java</category>
    </item>
  </channel>
</rss>
