0

I am currently trying to prepare a JSON body for an API call, which should look something like this

curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/api/alert -d '{
  "title": "Other alert",
  "description": "alert description",
  "type": "external",
  "source": "instance1",
  "sourceRef": "alert-ref",
  "severity": 3,
  "tlp": 3,
  "artifacts": [
    { "dataType": "ip", "data": "127.0.0.1", "message": "localhost" },
    { "dataType": "domain", "data": "thehive-project.org", "tags": ["home", "TheHive"] },
  ],
  "caseTemplate": "external-alert"
}'

The problem however is that my json body which I create with powershell has weird characters and don't see where the problem is. This is my JSON Body

{
    "tlp":  1,
    "source":  "Test",
    "title":  "Test Alert1",
    "artifacts":  "{\r\n    \"dataType\":  \"ip\",\r\n    \"data\":  \"127.0.0.1\"\r\n}",
    "type":  "external",
    "sourceRef":  "1",
    "description":  "Test",
    "severity":  1
}

I create this JSON body as follows. I have already tried CustomObjects and Hashtables, but always get the same output

$body = @{
            title = "$title"
            description = "$Alert_Description"
            type ="external"
            source ="$Source"
            sourceRef ="$SourceRef"
            severity = $Severity
            tlp = $tlp
            $artifacts = [PSCustomObject]@{
            dataType=ip
            data=127.0.0.1}  
        }| ConvertTo-Json
        $JsonBody = $body | ConvertTo-Json

Can somebody give me a hint? I have no clue anymore

2
  • 1
    Why are you converting to json twice? $body will already be JSON strings. Commented Aug 24, 2021 at 20:38
  • @AdminOfThings I thought maybe a nested Json would help.. but that wasn't the case Commented Aug 24, 2021 at 20:51

2 Answers 2

3

First, fix your hashtable so that it creates the intended JSON representation, and only apply ConvertTo-Json once:

$body = [ordered] @{
  title       = $title
  description = $Alert_Description
  type        = 'external'
  source      = $Source
  sourceRef   = $SourceRef
  severity    = $Severity
  tlp         = $tlp
  artifacts   = , [pscustomobject] @{
    dataType = 'ip'
    data     = '127.0.0.1'
  }  
} | ConvertTo-Json
  • Variables don't need enclosing in "..." unless you explicitly want to convert their values to strings.

  • Literal textual information such as ip does require quoting ('...', i.e. a verbatim string literal, is best).

  • The artifacts property is an array in your sample JSON, so the unary form of ,, the array constructor operator is used to wrap the [pscustomobject] instance in a single-element array.

    • If you have multiple objects, place , between them; if the array was constructed previously and stored in a variable named, say, $arr, use artifacts = $arr.
  • Use of [ordered], i.e. the creation of an ordered hashtable isn't strictly necessary, but makes it easier to compare the resulting JSON representation to the input hashtable.

  • Generally keep in mind that explicit use of a -Depth argument with ConvertTo-Json is situationally required in order to ensure that properties aren't truncated - see this post for more information. However, with the hashtable in your question this happens not to be a problem.


Second, since you're sending the json to an external program, curl (note that in Windows PowerShell you'd have to use curl.exe in order to bypass the built-in curl alias for Invoke-WebRequest, an additional escaping step is - unfortunately - required up to at least v7.1 - though that may change in v7.2: The " instances embedded in the value of $body must manually be escaped as \", due to a long-standing bug in PowerShell:

curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' `
  http://127.0.0.1:9000/api/alert -d ($body -replace '([\\]*)"', '$1$1\"')

Note: With your particular sample JSON, -replace '"', '\"' would do.

See this answer for more information.

2
  • The main problem was the "" around the variables, I didn't know that this creates some weird characters.. But I'm a bit confused about the artifacts part. I've tried to add two abjects to the artifacts properties like that, but it didn't work $collection = New-Object System.Collections.ArrayList $collection.Add([pscustomobject] @{dataType = 'username' data = $Username}) $collection.Add([pscustomobject] @{dataType = 'username' data = $Username}) artifacts = $collection.ForEach($_) Commented Aug 25, 2021 at 10:46
  • @StefanRöthlisberger: Enclosing a variable reference in "..." in essence calls .ToString() on the variable, using the invariant culture, and has special handling for arrays, which stringify as a space-separated list of their (stringified) elements (try "$(1,2,3)". As for the artifacts part: artifacts = $collection
    – mklement0
    Commented Aug 25, 2021 at 12:23
1

Slap a "-Depth 50" on your ConvertTo-Json, that should solve your issue.

Like here: ConvertTo-Json flattens arrays over 3 levels deep

1
  • While this is a good tip in general, -Depth is not required to get a full JSON representation of the hashtable in the question (it isn't nested deeply enough to be a problem), whereas there are other, obvious problems with the code.
    – mklement0
    Commented Aug 25, 2021 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.