{"id":299,"date":"2024-03-06T18:41:00","date_gmt":"2024-03-06T18:41:00","guid":{"rendered":"http:\/\/blog.firatyasar.com\/?p=299"},"modified":"2024-03-31T19:02:27","modified_gmt":"2024-03-31T19:02:27","slug":"container-image-scan-code-scan-with-blackduck","status":"publish","type":"post","link":"https:\/\/blog.firatyasar.com\/?p=299","title":{"rendered":"Container image scan &#038; code scan with BlackDuck"},"content":{"rendered":"\n<p>Black Duck Software, \u015firketlerin a\u00e7\u0131k kaynak kodlu yaz\u0131l\u0131m bile\u015fenlerinin kullan\u0131m\u0131n\u0131 ve uyumlulu\u011funu y\u00f6netmelerine yard\u0131mc\u0131 olan bir yaz\u0131l\u0131m ve hizmet sa\u011flay\u0131c\u0131s\u0131d\u0131r. Black Duck&#8217;un en pop\u00fcler \u00fcr\u00fcn\u00fc olan &#8220;Black Duck Hub&#8221;, a\u00e7\u0131k kaynak kodlu bile\u015fenlerin tarama ve y\u00f6netimini kolayla\u015ft\u0131ran bir ara\u00e7t\u0131r. Bu ara\u00e7, yaz\u0131l\u0131m geli\u015ftiricilerinin yaz\u0131l\u0131m projelerinde kulland\u0131klar\u0131 a\u00e7\u0131k kaynak kodlu bile\u015fenleri izlemelerine, g\u00fcvenlik a\u00e7\u0131klar\u0131 ve lisans uyumlulu\u011fu gibi \u00f6nemli fakt\u00f6rleri de\u011ferlendirmelerine olanak tan\u0131r.<\/p>\n\n\n\n<p>Bu makalede yazd\u0131\u011f\u0131m ve \u00e7ok yo\u011fun \u015fekilde kulland\u0131\u011f\u0131m hem image repository \u00fczerindeki hem de code seviyesinde scan yapman\u0131z\u0131 sa\u011flayan scriptimi sizinle payla\u015fmak istiyorum. Burada iki adet script bulunuyor. Ana script ile detect scriptini belli fonsiyonlar ile \u00e7a\u011f\u0131r\u0131p scan i\u015flemlerini yapaca\u011f\u0131z. \u00c7a\u011f\u0131raca\u011f\u0131m\u0131z script detect8 isimli bir script olacak. Synopsys detect&#8217;e ait Blackduck ile uyum i\u00e7inde \u00e7al\u0131\u015fan bu bile\u015fenin black duck ile ili\u015fkisini biraz daha a\u00e7al\u0131m.<\/p>\n\n\n\n<p>Synopsys Detect ve Black Duck aras\u0131ndaki ili\u015fki, Synopsys Detect&#8217;in Black Duck&#8217;un bile\u015fen veritaban\u0131na ve analiz teknolojisine dayanarak a\u00e7\u0131k kaynak bile\u015fenlerin tarama ve y\u00f6netimini ger\u00e7ekle\u015ftirmesidir. Bu entegrasyon sayesinde, geli\u015ftiriciler a\u00e7\u0131k kaynak kodlu bile\u015fenlerin g\u00fcvenlik a\u00e7\u0131klar\u0131, lisans uyumlulu\u011fu ve di\u011fer risklerini tespit edebilir ve bu bilgileri geli\u015ftirme s\u00fcrecinde kullanabilirler.<\/p>\n\n\n\n<p>K\u0131sacas\u0131, Synopsys Detect, Black Duck&#8217;un sa\u011flad\u0131\u011f\u0131 veritaban\u0131 ve analiz teknolojisi \u00fczerine in\u015fa edilmi\u015f bir ara\u00e7t\u0131r ve a\u00e7\u0131k kaynak bile\u015fenlerin g\u00fcvenlik ve uyumluluk y\u00f6netimini kolayla\u015ft\u0131rmak i\u00e7in kullan\u0131l\u0131r.<\/p>\n\n\n\n<p>\u015eimdi ana scriptimiz ile ayn\u0131 dizinde bulunan detect8.sh isimli scriptimizi olu\u015ftural\u0131m.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n# downloaded on 2023-04-25 from:\n# https:\/\/detect.synopsys.com\/detect8.sh\n\necho \"Detect Shell Script ${SCRIPT_VERSION}\"\n\nget_path_separator() {\n  # Performs a check to see if the system is Windows based.\n  if &#91;&#91; `uname` == *\"NT\"* ]] || &#91;&#91; `uname` == *\"UWIN\"* ]]; then\n    echo \"\\\\\"\n  else\n    echo \"\/\"\n  fi\n}\n\n# DETECT_LATEST_RELEASE_VERSION should be set in your\n# environment if you wish to use a version different\n# from LATEST.\nDETECT_RELEASE_VERSION=${DETECT_LATEST_RELEASE_VERSION}\n\n# To override the default version key, specify a\n# different DETECT_VERSION_KEY in your environment and\n# *that* key will be used to get the download url from\n# artifactory. These DETECT_VERSION_KEY values are\n# properties in Artifactory that resolve to download\n# urls for the detect jar file. As of 2022-12-07, the\n# available DETECT_VERSION_KEY values are:\n#\n# Every new major version of detect will have its own\n# DETECT_LATEST_X key.\nDETECT_VERSION_KEY=${DETECT_VERSION_KEY:-DETECT_LATEST_8}\n\n# You can specify your own download url from\n# artifactory which can bypass using the property keys\n# (this is mainly for QA purposes only)\nDETECT_SOURCE=${DETECT_SOURCE:-}\n\n# To override the default location of $HOME\/synopsys-detect, specify\n# your own DETECT_JAR_DOWNLOAD_DIR in your environment and\n# *that* location will be used.\n# *NOTE* We currently do not support spaces in the\n# DETECT_JAR_DOWNLOAD_DIR.\nDEFAULT_DETECT_JAR_DOWNLOAD_DIR=\"${HOME}$(get_path_separator)synopsys-detect$(get_path_separator)download\"\nif &#91;&#91; -z \"${DETECT_JAR_DOWNLOAD_DIR}\" ]]; then\n\t# If new name not set: Try old name for backward compatibility\n    DETECT_JAR_DOWNLOAD_DIR=${DETECT_JAR_PATH:-${DEFAULT_DETECT_JAR_DOWNLOAD_DIR}}\nfi\nDETECT_JAR_DOWNLOAD_DIR=${DETECT_JAR_DOWNLOAD_DIR:-${DEFAULT_DETECT_JAR_DOWNLOAD_DIR}}\n\n# To control which java detect will use to run, specify\n# the path in in DETECT_JAVA_PATH or JAVA_HOME in your\n# environment, or ensure that java is first on the path.\n# DETECT_JAVA_PATH will take precedence over JAVA_HOME.\n# JAVA_HOME will take precedence over the path.\n# Note: DETECT_JAVA_PATH should point directly to the\n# java executable. For JAVA_HOME the java executable is\n# expected to be in JAVA_HOME\/bin\/java\nDETECT_JAVA_PATH=${DETECT_JAVA_PATH:-}\n\n# If you want to pass any java options to the\n# invocation, specify DETECT_JAVA_OPTS in your\n# environment. For example, to specify a 6 gigabyte\n# heap size, you would set DETECT_JAVA_OPTS=-Xmx6G.\nDETECT_JAVA_OPTS=${DETECT_JAVA_OPTS:-}\n\n# If you want to pass any additional options to\n# curl, specify DETECT_CURL_OPTS in your environment.\n# For example, to specify a proxy, you would set\n# DETECT_CURL_OPTS=--proxy http:\/\/myproxy:3128\nDETECT_CURL_OPTS=${DETECT_CURL_OPTS:-}\n\n# If you only want to download the appropriate jar file set\n# this to 1 in your environment. This can be useful if you\n# want to invoke the jar yourself but do not want to also\n# get and update the jar file when a new version releases.\nDETECT_DOWNLOAD_ONLY=${DETECT_DOWNLOAD_ONLY:-0}\n\nSCRIPT_ARGS=\"\"\nfor NEXT_ARG in \"$@\"\ndo\n    SCRIPT_ARGS+=\"\\\"${NEXT_ARG}\\\" \"\ndone\n\nLOGGABLE_SCRIPT_ARGS=\"\"\n\n# This provides a way to get the script version (via, say, grep\/sed). Do not change.\nSCRIPT_VERSION=3.0.1\n\necho \"Detect Shell Script ${SCRIPT_VERSION}\"\n\nDETECT_BINARY_REPO_URL=https:\/\/sig-repo.synopsys.com\n\nfor i in $*; do\n  if &#91;&#91; $i == --blackduck.hub.password=* ]]; then\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS --blackduck.hub.password=&lt;redacted>\"\n  elif &#91;&#91; $i == --blackduck.hub.proxy.password=* ]]; then\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS --blackduck.hub.proxy.password=&lt;redacted>\"\n  elif &#91;&#91; $i == --blackduck.hub.api.token=* ]]; then\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS --blackduck.hub.api.token=&lt;redacted>\"\n  elif &#91;&#91; $i == --blackduck.password=* ]]; then\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS --blackduck.password=&lt;redacted>\"\n  elif &#91;&#91; $i == --blackduck.proxy.password=* ]]; then\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS --blackduck.proxy.password=&lt;redacted>\"\n  elif &#91;&#91; $i == --blackduck.api.token=* ]]; then\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS --blackduck.api.token=&lt;redacted>\"\n  elif &#91;&#91; $i == --polaris.access.token=* ]]; then\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS --polaris.access.token=&lt;redacted>\"\n  else\n    LOGGABLE_SCRIPT_ARGS=\"$LOGGABLE_SCRIPT_ARGS $i\"\n  fi\ndone\n\nrun() {\n  get_detect\n  if &#91;&#91; ${DETECT_DOWNLOAD_ONLY} -eq 0 ]]; then\n    run_detect\n  fi\n}\n\nget_detect() {\n  PATH_SEPARATOR=$(get_path_separator)\n  USE_LOCAL=0\n  LOCAL_FILE=\"${DETECT_JAR_DOWNLOAD_DIR}${PATH_SEPARATOR}synopsys-detect-last-downloaded-jar.txt\"\n  if &#91;&#91; -z \"${DETECT_SOURCE}\" ]]; then\n    if &#91;&#91; -z \"${DETECT_RELEASE_VERSION}\" ]]; then\n      VERSION_CURL_CMD=\"curl ${DETECT_CURL_OPTS} --silent --header \\\"X-Result-Detail: info\\\" '${DETECT_BINARY_REPO_URL}\/api\/storage\/bds-integrations-release\/com\/synopsys\/integration\/synopsys-detect?properties=${DETECT_VERSION_KEY}'\"\n      VERSION_EXTRACT_CMD=\"${VERSION_CURL_CMD} | grep \\\"${DETECT_VERSION_KEY}\\\" | sed 's\/&#91;^&#91;]*&#91;^\\\"]*\\\"\\(&#91;^\\\"]*\\).*\/\\1\/'\"\n      DETECT_SOURCE=$(eval ${VERSION_EXTRACT_CMD})\n      if &#91;&#91; -z \"${DETECT_SOURCE}\" ]]; then\n        echo \"Unable to derive the location of ${DETECT_VERSION_KEY} from response to: ${VERSION_CURL_CMD}\"\n        USE_LOCAL=1\n      fi\n    else\n      DETECT_SOURCE=\"${DETECT_BINARY_REPO_URL}\/bds-integrations-release\/com\/synopsys\/integration\/synopsys-detect\/${DETECT_RELEASE_VERSION}\/synopsys-detect-${DETECT_RELEASE_VERSION}.jar\"\n    fi\n  fi\n\n  if &#91;&#91; USE_LOCAL -eq 0 ]]; then\n    echo \"Will look for : ${DETECT_SOURCE}\"\n  else\n    echo \"Will look for : ${LOCAL_FILE}\"\n  fi\n\n  if &#91;&#91; USE_LOCAL -eq 1 ]] &amp;&amp; &#91;&#91; -f \"${LOCAL_FILE}\" ]]; then\n    echo \"Found local file ${LOCAL_FILE}\"\n    DETECT_FILENAME=`cat ${LOCAL_FILE}`\n  elif &#91;&#91; USE_LOCAL -eq 1 ]]; then\n    echo \"${LOCAL_FILE} is missing and unable to communicate with a Detect source.\"\n    exit -1\n  else\n    DETECT_FILENAME=${DETECT_FILENAME:-$(awk -F \"\/\" '{print $NF}' &lt;&lt;&lt; $DETECT_SOURCE)}\n  fi\n  DETECT_DESTINATION=\"${DETECT_JAR_DOWNLOAD_DIR}${PATH_SEPARATOR}${DETECT_FILENAME}\"\n\n  USE_REMOTE=1\n  if &#91;&#91; USE_LOCAL -ne 1 ]] &amp;&amp; &#91;&#91; ! -f \"${DETECT_DESTINATION}\" ]]; then\n    echo \"You don't have the current file, so it will be downloaded.\"\n  else\n    echo \"You have already downloaded the latest file, so the local file will be used.\"\n    USE_REMOTE=0\n  fi\n\n  if &#91; ${USE_REMOTE} -eq 1 ]; then\n    echo \"getting ${DETECT_SOURCE} from remote\"\n    TEMP_DETECT_DESTINATION=\"${DETECT_DESTINATION}-temp\"\n    curlReturn=$(curl ${DETECT_CURL_OPTS} --silent -w \"%{http_code}\" -L -o \"${TEMP_DETECT_DESTINATION}\" --create-dirs \"${DETECT_SOURCE}\")\n    if &#91;&#91; 200 -eq ${curlReturn} ]]; then\n      mv \"${TEMP_DETECT_DESTINATION}\" \"${DETECT_DESTINATION}\"\n      if &#91;&#91; -f ${LOCAL_FILE} ]]; then\n        rm \"${LOCAL_FILE}\"\n      fi\n      echo \"${DETECT_FILENAME}\" >> \"${LOCAL_FILE}\"\n      echo \"saved ${DETECT_SOURCE} to ${DETECT_DESTINATION}\"\n    else\n      echo \"The curl response was ${curlReturn}, which is not successful - please check your configuration and environment.\"\n      exit -1\n    fi\n  fi\n}\n\nset_detect_java_path() {\n  PATH_SEPARATOR=$(get_path_separator)\n\n  if &#91;&#91; -n \"${DETECT_JAVA_PATH}\" ]]; then\n    echo \"Java Source: DETECT_JAVA_PATH=${DETECT_JAVA_PATH}\"\n  elif &#91;&#91; -n \"${JAVA_HOME}\" ]]; then\n    DETECT_JAVA_PATH=\"${JAVA_HOME}${PATH_SEPARATOR}bin${PATH_SEPARATOR}java\"\n    echo \"Java Source: JAVA_HOME${PATH_SEPARATOR}bin${PATH_SEPARATOR}java=${DETECT_JAVA_PATH}\"\n  else\n    echo \"Java Source: PATH\"\n    DETECT_JAVA_PATH=\"java\"\n  fi\n}\n\nrun_detect() {\n  set_detect_java_path\n\n  JAVACMD=\"\\\"${DETECT_JAVA_PATH}\\\" ${DETECT_JAVA_OPTS} -jar \\\"${DETECT_DESTINATION}\\\"\"\n  echo \"running Detect: ${JAVACMD} ${LOGGABLE_SCRIPT_ARGS}\"\n\n  eval \"${JAVACMD} ${SCRIPT_ARGS}\"\n  RESULT=$?\n  echo \"Result code of ${RESULT}, exiting\"\n  exit ${RESULT}\n}\n\nrun<\/code><\/pre>\n\n\n\n<p>Detect8.sh isimli scriptimizi olu\u015ftutup kaydettikten sonra bunu \u00e7a\u011f\u0131raca\u011f\u0131m\u0131z fonksiyonlar\u0131 i\u00e7eren main scriptimiz scan_microservice.sh&#8217;\u0131 olu\u015ftural\u0131m.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n\nfunction prepare_environment() {\n  if &#91;&#91; -z \"${BLACK_DUCK_TOKEN}\" ]]; then\n    echo \"black duck api token was not provided, aborting\"\n    exit 1\n  fi\n  if &#91;&#91; -z \"${GITHUB_USER}\" ]]; then\n    echo \"github user was not provided, aborting\"\n    exit 1\n  fi\n  if &#91;&#91; -z \"${GITHUB_PERSONAL_ACCESS_TOKEN}\" ]]; then\n    echo \"github personal access token was not provided, aborting\"\n    exit 1\n  fi\n  \n  Green='\\033&#91;0;32m'\n  NC='\\033&#91;0m'\n  \n  readonly BLACK_DUCK_PROJECT_NAME=\"&lt;black-duck-project-name>\"\n  readonly BLACK_DUCK_TIMEOUT=\"300\"\n  readonly BLACK_DUCK_URL=\"&lt;black-duck-url>\"\n  readonly DOCKER_REGISTRY_URL=\"&lt;registry-url>\"\n}\n\nfunction execute_docker_image_scan() {\n  declare -a DOCKER_IMAGES_MICROSERVICES=(\n    \"docker-image-1:latest\"\n    \"docker-image-2:latest\"\n  )\n  for DOCKER_IMAGE in \"${DOCKER_IMAGES_MICROSERVICES&#91;@]}\"; do\n    echo -e \"${Green}****************** BlackDuck scan has been started for docker image: '${DOCKER_IMAGE}' ******************${NC}\"\n    DOCKER_IMAGE_VERSION=$(cut -d \":\" -f2 &lt;&lt;&lt;\"${DOCKER_IMAGE}\")\n    bash .\/detect8.sh \\\n      --blackduck.url=\"${BLACK_DUCK_URL}\" \\\n      --blackduck.api.token=\"${BLACK_DUCK_TOKEN}\" \\\n      --detect.project.name=\"${BLACK_DUCK_PROJECT_NAME}\" \\\n      --detect.project.version.name=\"${DOCKER_IMAGE_VERSION}\" \\\n      --detect.timeout=\"${BLACK_DUCK_TIMEOUT}\" \\\n      --detect.tools=DOCKER \\\n      --detect.docker.image=\"${DOCKER_REGISTRY_URL}\/${DOCKER_IMAGE}\" \\\n      --detect.detector.search.continue=true\n    echo -e \"${Green}****************** BlackDuck scan has been finished for docker image: '${DOCKER_IMAGE}' ******************${NC}\"\n    echo \"\"\n  done\n}\n\nfunction execute_code_scan() {\n  declare -a MICROSERVICES_WITH_VERSIONS=(\n    \"docker-image-1:latest\"\n    \"docker-image-2:latest\"\n  )\n  readonly GITHUB_URL=\"&lt;write github url here with token>\"\n\n  for MICROSERVICE_WITH_VERSION in \"${MICROSERVICES_WITH_VERSIONS&#91;@]}\"; do\n    MICROSERVICE_NAME=$(cut -d \":\" -f1 &lt;&lt;&lt;\"${MICROSERVICE_WITH_VERSION}\")\n    MICROSERVICE_VERSION=$(cut -d \":\" -f2 &lt;&lt;&lt;\"${MICROSERVICE_WITH_VERSION}\")\n    GIT_REPO_DIR=\"repo-to-scan\"\n    \n    echo -e \"${Green}****************** BlackDuck scan has been started for code of service: '${MICROSERVICE_NAME}' ******************${NC}\"\n    git clone \"${GITHUB_URL}\/${MICROSERVICE_NAME}.git\" \"${GIT_REPO_DIR}\"\n    bash .\/detect8.sh \\\n      --blackduck.url=\"${BLACK_DUCK_URL}\" \\\n      --blackduck.api.token=\"${BLACK_DUCK_TOKEN}\" \\\n      --detect.project.name=\"${BLACK_DUCK_PROJECT_NAME}\" \\\n      --detect.project.version.name=\"${MICROSERVICE_VERSION}\" \\\n      --detect.timeout=\"${BLACK_DUCK_TIMEOUT}\" \\\n      --detect.tools=DETECTOR \\\n      --detect.source.path=\"${GIT_REPO_DIR}\" \\\n      --detect.code.location.name=\"${GIT_REPO_DIR}\" \\\n      --detect.detector.search.continue=true \\\n      --detect.maven.build.command='--settings=actions-settings.xml'\n\n    rm -rf \"${GIT_REPO_DIR}\"\n    echo -e \"${Green}****************** BlackDuck scan has been finished for code of service: '${MICROSERVICE_NAME}' ******************${NC}\"\n    echo \"\"\n  done\n}\n\nwhile getopts \"p:t:u:\" arg; do\n  case \"${arg}\" in\n  p)\n    GITHUB_PERSONAL_ACCESS_TOKEN=\"${OPTARG}\"\n    ;;\n  t)\n    BLACK_DUCK_TOKEN=\"${OPTARG}\"\n    ;;\n  u)\n    GITHUB_USER=\"${OPTARG}\"\n    ;;\n  *)\n    print_usage\n    exit 1\n    ;;\n  esac\ndone\nshift $((OPTIND - 1))\n\nprepare_environment\nexecute_docker_image_scan\nexecute_code_scan<\/code><\/pre>\n\n\n\n<p>Burada dikkat edilecek nokta \u015fudur. Script i\u00e7in gerekli de\u011fi\u015fiklikleri kendi ortam\u0131n\u0131za ili\u015fkin bilgiler ile de\u011fi\u015ftirilmelidir.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>readonly BLACK_DUCK_PROJECT_NAME=\"&lt;black-duck-project-name>\"\nreadonly BLACK_DUCK_TIMEOUT=\"300\"\nreadonly BLACK_DUCK_URL=\"&lt;black-duck-url>\"\nreadonly DOCKER_REGISTRY_URL=\"&lt;registry-url>\"<\/code><\/pre>\n\n\n\n<p>Ek olarak kodun bulundu\u011fu github url&#8217;i de token&#8217;l\u0131 olacak \u015fekilde de\u011fi\u015fkene de\u011fer olarak verilmelidir.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>readonly GITHUB_URL=\"&lt;write github url here with token>\"<\/code><\/pre>\n\n\n\n<p>Ard\u0131ndan script tetiklendi\u011finde a\u015fa\u011f\u0131daki 3 fonksiyon tetiklenerek repository ve code base taraf\u0131nda black duck taraf\u0131ndan scan i\u015flemleri ger\u00e7ekle\u015ftirilerek bir rapor olu\u015fturulacakt\u0131r.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"520\" height=\"190\" src=\"\/wp-content\/uploads\/2024\/03\/image-35.png\" alt=\"\" class=\"wp-image-300\" srcset=\"\/wp-content\/uploads\/2024\/03\/image-35.png 520w, \/wp-content\/uploads\/2024\/03\/image-35-300x110.png 300w\" sizes=\"(max-width: 520px) 100vw, 520px\" \/><\/figure>\n\n\n\n<p>Herkes i\u00e7in olduk\u00e7a faydal\u0131 olacak bir g\u00fcvenlik tool&#8217;un olan Blackduck i\u00e7in bu scripti pipeline&#8217;lar\u0131n\u0131za da kolayl\u0131kla entegre edebilirsiniz.<\/p>\n\n\n\n<p>Script d\u00fczg\u00fcn \u015fekilde \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda \u00e7\u0131kt\u0131 a\u015fa\u011f\u0131daki gibi olacakt\u0131r.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"201\" src=\"\/wp-content\/uploads\/2024\/03\/image-37-1024x201.png\" alt=\"\" class=\"wp-image-302\" srcset=\"\/wp-content\/uploads\/2024\/03\/image-37-1024x201.png 1024w, \/wp-content\/uploads\/2024\/03\/image-37-300x59.png 300w, \/wp-content\/uploads\/2024\/03\/image-37-768x150.png 768w, \/wp-content\/uploads\/2024\/03\/image-37-1536x301.png 1536w, \/wp-content\/uploads\/2024\/03\/image-37-660x129.png 660w, \/wp-content\/uploads\/2024\/03\/image-37.png 1766w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Cheers.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Black Duck Software, \u015firketlerin a\u00e7\u0131k kaynak kodlu yaz\u0131l\u0131m bile\u015fenlerinin kullan\u0131m\u0131n\u0131 ve uyumlulu\u011funu y\u00f6netmelerine yard\u0131mc\u0131 olan bir yaz\u0131l\u0131m ve hizmet sa\u011flay\u0131c\u0131s\u0131d\u0131r. Black Duck&#8217;un en pop\u00fcler \u00fcr\u00fcn\u00fc olan &#8220;Black Duck Hub&#8221;, a\u00e7\u0131k kaynak kodlu bile\u015fenlerin tarama ve y\u00f6netimini kolayla\u015ft\u0131ran bir ara\u00e7t\u0131r. Bu ara\u00e7, yaz\u0131l\u0131m geli\u015ftiricilerinin yaz\u0131l\u0131m projelerinde kulland\u0131klar\u0131 a\u00e7\u0131k kaynak kodlu bile\u015fenleri izlemelerine, g\u00fcvenlik a\u00e7\u0131klar\u0131 ve lisans\u2026 <span class=\"read-more\"><a href=\"https:\/\/blog.firatyasar.com\/?p=299\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":301,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[117,118,45,119],"_links":{"self":[{"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=\/wp\/v2\/posts\/299"}],"collection":[{"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=299"}],"version-history":[{"count":1,"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=\/wp\/v2\/posts\/299\/revisions"}],"predecessor-version":[{"id":303,"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=\/wp\/v2\/posts\/299\/revisions\/303"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=\/wp\/v2\/media\/301"}],"wp:attachment":[{"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=299"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=299"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.firatyasar.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=299"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}