Searching Athena AWS WAF logs by http header - amazon-web-services

I've set up AWS WAF Logging to S3, and created an Athena table as described in the documentation ( https://docs.aws.amazon.com/athena/latest/ug/waf-logs.html )
However, http headers are stored as an array<struct<name: string, value: string>> not a map (for valid reasons). I'd like to write a query like
select headers.user-agent, headers.if-none-match from waf_logs where something;
if-none-match may or may not be present in the headers list.
using CROSS JOIN UNNEST(httprequest.headers) doesn't work, as this will create multiple rows. Using map notation doesn't work, as its a array of struct, not a map.
There are a lot of pages on the internet about how to set up the table, but not so many with worked examples of real-life queries, and none that I can find about how to query by nested attributes.
I'd really appreciate any suggestions. Thanks!

Here's a WAF query that should do the trick for request headers:
WITH waf_data AS (
SELECT
waf.action as action,
waf.httprequest.clientip as clientip,
waf.httprequest.country as country,
map_agg(f.name, f.value) AS kv
FROM "waf_logs" waf,
UNNEST(waf.httprequest.headers) AS t(f)
GROUP BY 1, 2, 3
)
SELECT
waf_data.action,
waf_data.clientip,
waf_data.country,
waf_data.kv['Host'] AS host,
waf_data.kv['User-Agent'] as UserAgent,
waf_data.kv['Cookie'] as cookie
FROM waf_data
WHERE waf_data.kv['Host'] like 'waf_alb.us-east-2.elb.amazonaws.com'
LIMIT 10;

I used the following to extract the HTTP header values (here Host field by name):
SELECT action, header.value as hostname, clientip, timestamp
from (
SELECT
httprequest.clientip as clientip,
action,
timestamp,
httprequest.headers as headers
FROM waf_logs
)
cross join unnest(headers) as c(header)
where lower(header.name) = 'host'
I used this post to extract the array of row which is formatted like array(row("name" varchar,"value" varchar)) in the waf logs database

Related

NetSuite REST API with Postman: Record not found while using Suiteql

I'm trying to query some records like vendor and customer using suiteql with REST API using Postman.
The issue is that it return everytime the same error:
"Invalid search query. Detailed unprocessed description follows. Search error occurred: Record 'customer' was not found."
I tried:
differents syntax like Customer, CUSTOMER, customers, Customers, CUSTOMERS
but no change.
I added customer access to the role.
Is there something to activate while using suiteql with rest api?
Can you first try with select * from customer and see if any results are returned and then go on appending your conditions like date created greater than this year start
SELECT id, companyname, email, datecreated
FROM customer
WHERE datecreated >= BUILTIN.RELATIVE_RANGES('TFY', 'START')
AND datecreated <= BUILTIN.RELATIVE_RANGES('TFY', 'END');
NetSuite doesn't say it but for a record to be searchable, the user needs to have the following permissions:
Transactions:
Find Transaction
All the records needed
Lists:
Perform search
All the records needed
Setup:
REST WEB Services
Log in using Access Tokens or Oauth 2.0
Reports:
SuiteAnalytics WorkBook

How does on implement Oracle Apex region authorization

The bind variable :app_region_id works region however it does not work for the authorization scheme
SQL statement for region
SELECT WORKSPACE,APPLICATION_ID , PAGE_ID, REGION_ID, REGION_NAME,AUTHORIZATION_SCHEME, :app_region_id
from apex_application_page_regions
where region_id = :app_region_id
Authorisation scheme
Scheme type: Exists SQL Query
SQL Query:
Select 1
from apex_application_page_regions
where region_id = :app_region_id;
which bind variable should I use to achieve region authorization. The code that I wanted to implement, it does not return the desired results
Select 1
from AD_GRP_APEX_REGION_ASSOC r,
AD_GRP_EMP e
where e.ad_grp = r.ad_grp
and e.user_id = :app_user
and r.region_id = :app_region_id
The variable :app_region_id is not a global variable in the same way as :APP_USER. Authorization schemas only work with global variables which are associated to the SESSION, not to a element in a page ( such is a region ). Besides that, it does not make any sense to have it because you use AUTHORIZATION SCHEMAS to limit access to different components in your application. Let me show how to apply authorization schemas to regions in Oracle Apex.
Let's imagine I have a test application with three regions:
Region 1 shows one field of a query ( one row )
Region 2 shows another field of a query ( one row )
Region 3 only shows a message ( static content )
Without any authentication schema, it shows this
Now, let's create an authorization schema example that derives who is the user and based on this will show only region 3. In my case my application uses the authentication schema by default ( apex users ) so the user logged is always assigned to the global variable :APP_USER.
Application Builder --> Shared Components --> Authorization schemas
Authorization Schema --> MY_TEST
Type --> Exist SQL QUERY
select 1 from dual where exists ( select user_name from apex_workspace_apex_users where workspace_name = 'MY_WORKSPACE' and user_name = upper(':APP_USER') )
This authorisation schema will forbid to see a region when the user exists, so basically for everybody, obviously I am doing it just for testing purposes.
Then I modified attributes of REGION 1 and REGION 2 , changing the authorization schema to MY_TEST
Now, when I execute the application , I can only see the region3 in the page.

WSO2 Stream Processor : Correlation during http response handling for http service calls

I have a hosted http service that accepts a trend data and returns some output. This service is accessed in siddhi query language as follows:
#sink(type='http-request', sink.id='trends',
publisher.url='${SERVICE_URL}', #map(type='json', #payload(""" {"trend":{{trendArray}} } """) ) )
define stream Request(item string, trendArray string);
#source(type='http-response' , sink.id='trends', http.status.code='200',
#map(type='json', #attributes(stock = '<HOW_TO_GET_THIS_VALUE>', output = "<HOW_TO_GET_THIS_VALUE>")
) )
define stream Response(item string, output string);
The http request(and response) payload doesn't include item name.
when the response comes we would like to assign item name against which we scored the output - marked as HOW_TO_GET_THIS_VALUE above.
How to accomplish this in siddhi query ?
How to treat the response data of as-is as pass to the field ?
I did not see a description of this scenario in siddhi. If not supported, it will good to know details of a custom extension (based out of http extension) for this scenario. Solution to add a proxy layer for http call is less desired.
After some experiments , HOW_TO_GET_THIS_VALUE = 'trp:item'. The http sink should also have this field even though its not used in payload.

Keycloak user attributes with multiple values (list)

I'm having a Keycloak use case where single user may have multiple customer numbers. These customer numbers would need to be sent to service provider / client and also be easily updated by administrators. Some users may have hundreds of customer numbers. Currently I'm using single user attribute named "customerNumbers" where the customer numbers are separated by comma but I'd like:
To offer the administrators possibility to see each customer number in its own field
To send the customer numbers as an JSON array instead of comma separated claim
So instead of this:
I'd like something like this:
And instead of this
"customers": {
"customerNumbers": "140661,140662"
},
I'd like something like this:
"customers": [
{"customerNumber": "140661"},
{"customerNumber": "140662"}
],
How should one approach this kind of situation?
Keyclaok use a custom format to save multiple value in the same field by separating multiple value with ##
key: customerNumbers value: 140661##140662
if you want to show that field on your jwt access token you can do it by creating a client scope -> protocol mapper (user attribute) for custom attribute making sure to set multivalued on
set custom attribute on protocol mapper:
After that you can add those mapper to your client so it will appear on your access token
set custom attribute on jwt token:
You need to add your values in the user attributes like this [{"customerNumber": "140661"}, {"customerNumber": "140662"}]
ie [Keycloak user management, attributes tab][1]
your client mapper will need be like this (i think i tried every other option)
enter image description here

Amazon Product API - URL response

is there anyway to dynamically generate the response for the Amazon Product API with using just a URL string?
I see there are PHP and C# libraries but I am just trying to browse to a URL and see the response. I noticed one of the required fields of the URL is a timestamp which makes this tricky. The following page helped to generate the URLs but I can't seem to find a way to do it dynamically?
http://associates-amazon.s3.amazonaws.com/scratchpad/index.html
Thanks!
This is the dynamic search for amazon product
Download aws_signed_request.php from this url
include('aws_signed_request.php');
$public_key = 'xxxxxxxx';
$private_key = 'xxxxxxxxxx';
$associate_tag = 'xxxxxx';
$keywords= 'PHP';
$search_index = 'Books';
// generate signed URL
$request = aws_signed_request('com', array(
'Operation' => 'ItemSearch',
'Keywords' => "Php Books",
"SearchIndex" => "Books",
"Count" => '24',
'ResponseGroup' => 'Large,EditorialReview'), $public_key, $private_key, $associate_tag);
// do request (you could also use curl etc.)
$response = #file_get_contents($request);
Documentation URL HERE
I'm not sure I totally understand your question, but I think the answer is "the data in the Amazon product API is only available via 'signed' URLs". That way, Amazon can track abuse, etc back to the source (i.e. the signer).
If it were possible to get the data with a "static" URL, then you could post that URL all over the Internet and anyone could get the data without signing up with Amazon. It's their data, and they have rules on it's use, so that wouldn't fly with them.
That said, you can usually create URLs with a timestamp in the future (months or even years). But you would still be responsible for it's use/abuse.