signed URL to post a file to S3 [duplicate] - amazon-web-services

This is my HTML POST Form.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="http://sigv4examplebucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
Key to upload:
<input type="input" name="key" value="user/user1/${filename}" /><br />
<input type="hidden" name="acl" value="public-read" />
<input type="hidden" name="success_action_redirect" value="http://sigv4examplebucket.s3.amazonaws.com/successful_upload.html" />
Content-Type:
<input type="input" name="Content-Type" value="image/jpeg" /><br />
<input type="hidden" name="x-amz-meta-uuid" value="14365123651274" />
<input type="hidden" name="x-amz-server-side-encryption" value="AES256" />
<input type="text" name="X-Amz-Credential" value="AKIAIOSFODNN7EXAMPLE/20151229/us-east-1/s3/aws4_request" />
<input type="text" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" />
<input type="text" name="X-Amz-Date" value="20151229T000000Z" />
Tags for File:
<input type="input" name="x-amz-meta-tag" value="" /><br />
<input type="hidden" name="Policy" value='<Base64-encoded policy string>' />
<input type="hidden" name="X-Amz-Signature" value="<signature-value>" />
File:
<input type="file" name="file" /> <br />
<!-- The elements after this will be ignored -->
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>
</html>
I got this from the AWS S3 Docs shown below.
https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
From AWS Console I have gotten my security credentials as shown below.
I am aware that I need to set values for "Policy" and "X-Amz-Signature" but I am not sure as to how to do that.
In the docs they have mentioned that I need to StringToSign and get the Policy/Signature but I am not sure how to do that.
Can someone help me as to how to generate Policy and Signature for my HTML FORM ?

You will have to calculate the signature from backend. Follow these details Calculating a Signature to implement at your own.
That would be something like this:
$kDate = hash_hmac('sha256', $short_date, 'AWS4' . $secret_key, true);
$kRegion = hash_hmac('sha256', $region, $kDate, true);
$kService = hash_hmac('sha256', "s3", $kRegion, true);
$kSigning = hash_hmac('sha256', "aws4_request", $kService, true);
$signature = hash_hmac('sha256', base64_encode($policy), $kSigning);
Or you can use any of the AWS SDKs of your choice.
For example using PHP SDK you would implement:
Aws\Signature\S3SignatureV4

Related

Upload to AWS S3 with createPresignedPost -- file either invisible in S3 or Policy Condition failed

Trying to upload to AWS S3 using createPresignedPost approach, but either the seemingly uploaded file is invisible or not showing in S3 bucket or "Policy Condition failed" error returned.
Need to upload files to AWS S3 bucke securely, so I try to generate a presigned post policy in Lambda. Then I copy the policy details into a test HTML form, then upload files. If I put in the "key" parameter like this: <input type="input" name="key" value="datafile/math3/${filename}" />, a "Policy Condition failed" error will return. Why? This seems to be the right way to set this parameter. But if I set "key" like this (remove the {filename} part"), <input type="input" name="key" value="datafile/math3/" />, the uploading seems to be successful. No error returned, I even see the folder "datafile/math3" got created in S3. But there is no file under the folder. If I check the size of the folder, the size roughly match the file I try to upload. No object showing up. Why?
Lambda code:
var policy;
var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: 'xxxxxxxxxxx', secretAccessKey: 'yyyyyyyyyyyyyyyyyyyyyyy'});
const s3 = new AWS.S3();
const key = 'datafile/math3/';
const params = {
Bucket: 'my-file-store',
Key: key,
Expires: 60*60, // in seconds,
Fields: {
key: key,
}
// Conditions: [
// // {'acl': 'public-read'},
// // ["starts-with", "$key", "datafile/math3/"],
// // {'key': 'datafile/math3/'}
// ]
};
s3.createPresignedPost(params, function(err, data) {
if (err) {
throw err;
}
else {
policy = data;
}
});
return policy;
I run this lambda code in test mode, and copy over the necessary info into the html code.
HTML code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="https://s3.amazonaws.com/my-file-store" method="post" enctype="multipart/form-data">
Key to upload:
<input type="input" name="key" value="datafile/math3/${filename}" /><br />
<!-- <input type="input" name="key" value="datafile/math3/" /><br /> -->
<!-- <input type="hidden" name="acl" value="public-read" /> -->
<!-- <input type="hidden" name="success_action_redirect" value="http://aztopia-file-store.s3.amazonaws.com/successful_upload.html" /> -->
Content-Type:
<!-- <input type="input" name="Content-Type" value="image/jpeg" /><br /> -->
<!-- <input type="hidden" name="x-amz-meta-uuid" value="14365123651274" /> -->
<!-- <input type="hidden" name="x-amz-server-side-encryption" value="AES256" /> -->
<input type="text" name="X-Amz-Credential" value="erzdfgsdfgsddgdffdfffxxxxxx/20190330/us-east-1/s3/aws4_request" />
<input type="text" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" />
<input type="text" name="X-Amz-Date" value="20190330T030853Z" />
Tags for File:
<!-- <input type="input" name="x-amz-meta-tag" value="" /><br /> -->
<input type="hidden" name="Policy" value='asdfasfadsfasdfasdfasrheghjfghjfhhjfgjghxxxxxxxxxxxxxxxxxxxxxxxxxxxx==' />
<input type="hidden" name="X-Amz-Signature" value="343rgwgdhgsfgsdfgdgdfgsdfgsdfgsdfgfdyyyyyyyy" />
File:
<input type="file" name="file" /> <br />
<!-- The elements after this will be ignored -->
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>
</html>
BTW, I have CORS setup in the bucket like below.
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Now why it does not like me to set key like this:<input type="input" name="key" value="datafile/math3/${filename}" />? From all sources, the {filename} part seems necessary.
If I remove ${filename}, I kinda know it cannot put the object correctly since it does not know the filename.
What do I miss here?
Another maybe related point: if I add the <input type="hidden" name="acl" value="public-read" />parameter in both lambda and html form, (commented out now), I got an "access denied" error. Why is that?
Tried many other combinations like starts-with condition too. No avail.
Much appreciation for looking! Been struggling for the whole day.

Browser Based File Upload on AWS S3 using POST Request

This is my HTML POST Form.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="http://sigv4examplebucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
Key to upload:
<input type="input" name="key" value="user/user1/${filename}" /><br />
<input type="hidden" name="acl" value="public-read" />
<input type="hidden" name="success_action_redirect" value="http://sigv4examplebucket.s3.amazonaws.com/successful_upload.html" />
Content-Type:
<input type="input" name="Content-Type" value="image/jpeg" /><br />
<input type="hidden" name="x-amz-meta-uuid" value="14365123651274" />
<input type="hidden" name="x-amz-server-side-encryption" value="AES256" />
<input type="text" name="X-Amz-Credential" value="AKIAIOSFODNN7EXAMPLE/20151229/us-east-1/s3/aws4_request" />
<input type="text" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" />
<input type="text" name="X-Amz-Date" value="20151229T000000Z" />
Tags for File:
<input type="input" name="x-amz-meta-tag" value="" /><br />
<input type="hidden" name="Policy" value='<Base64-encoded policy string>' />
<input type="hidden" name="X-Amz-Signature" value="<signature-value>" />
File:
<input type="file" name="file" /> <br />
<!-- The elements after this will be ignored -->
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>
</html>
I got this from the AWS S3 Docs shown below.
https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
From AWS Console I have gotten my security credentials as shown below.
I am aware that I need to set values for "Policy" and "X-Amz-Signature" but I am not sure as to how to do that.
In the docs they have mentioned that I need to StringToSign and get the Policy/Signature but I am not sure how to do that.
Can someone help me as to how to generate Policy and Signature for my HTML FORM ?
You will have to calculate the signature from backend. Follow these details Calculating a Signature to implement at your own.
That would be something like this:
$kDate = hash_hmac('sha256', $short_date, 'AWS4' . $secret_key, true);
$kRegion = hash_hmac('sha256', $region, $kDate, true);
$kService = hash_hmac('sha256', "s3", $kRegion, true);
$kSigning = hash_hmac('sha256', "aws4_request", $kService, true);
$signature = hash_hmac('sha256', base64_encode($policy), $kSigning);
Or you can use any of the AWS SDKs of your choice.
For example using PHP SDK you would implement:
Aws\Signature\S3SignatureV4

ColdFusion not adding variable to url

Currently I'm in the works of creating a refrral system for my website, but somehow ColdFusion won't let me add a value to an URL.
When people sign up, they use a referral url which looks like this: /register/?referer=[name]. Followed by the following form:
<cfif IsDefined('URL.referer')>
<cfquery name="CheckRefer" datasource = "#DSN#">
SELECT username, ip_reg, look
FROM users
WHERE username='<cfoutput>#referer#</cfoutput>'
</cfquery> </cfif>
<form id="register_step_two" method="post" action="complete.cfm<cfif #referer# is not 0 and #CheckRefer.RecordCount# is 1 and #CGI.REMOTE_ADDR# is not #CheckRefer.ip_reg#>?referer=<cfoutput>#referer#</cfoutput></cfif>">
<input type="hidden" name="referer" id="referer" value="#referer#" />
<input type="hidden" name="email" id="email" value="#form.email#" />
<input type="hidden" name="bdday" id="bdday" value="#form.bdday#" />
<input type="hidden" name="bdmonth" id="bdmonth" value="#form.bdmonth#" />
<input type="hidden" name="bdyear" id="bdyear" value="#form.bdyear#">
<input type="hidden" name="username" id="username" value="" />
<input type="hidden" name="figure" id="figure" value="hr-834-61.hd-600-4.ch-3014-110.lg-3006-110-62.sh-3089-110.ca-3217-62-62,s-0.g-0.d-4.h-4.a-0,c201c1c1b7fceffd8d5e8f5204f593ef" />
<input type="hidden" name="password" id="password" value="#form.password#" />
<input type="submit" value="Registreer" id="register-button" onmousedown="this.style.backgroundColor='##ddd';" onmouseup="this.style.backgroundColor='##eee';" onmouseover="this.style.backgroundColor='##eee';" onmouseout="this.style.backgroundColor='##fff';" disabled="disabled" />
</form>
But after clicking the submit button it redirects me to complete.cfm and not complete.cfm?referer=[name]. I don't know why this happens, because I'm using the same method on other pages. All the variables inside the are defined...
For example: this form works perfectly fine (the code posted above is page 2 of 3 from my signup process, and this one underneed is the first one, page 3 is the complete.cfm).
<cfif IsDefined('URL.referer')>
<cfquery name="CheckRefer" datasource = "#DSN#">
SELECT username, ip_reg, look
FROM users
WHERE username='<cfoutput>#referer#</cfoutput>'
</cfquery> </cfif>
<form id="register_step_one" method="post" action="step2.cfm<cfif IsDefined('URL.referer') and URL.referer is not 0 and #CheckRefer.RecordCount# is 1 and #CGI.REMOTE_ADDR# is not #CheckRefer.ip_reg#>?referer=<cfoutput>#referer#</cfoutput></cfif>">
<label for="email">Email</label><br />
<input type="text" name="email" id="formemail" />
<div class="errormsg display_none" id="habbo_name_message_box">
<h3>Eoutmelding</h3>
Something went wrong..
</div>
<br /><br />
<label for="password">New password</label><br />
<input type="password" name="password" id="formpassword" />
<br /><br>
<label for="cpassword">Repeat password<label><br />
<input type="password" name="cpassword" id="formcpassword" />
<br /><br />
Date of birth:<br />
<select name="bdday" id="bdday" class="dateselector"><option value="">Dag</option><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option><option value="24">24</option><option value="25">25</option><option value="26">26</option><option value="27">27</option><option value="28">28</option><option value="29">29</option><option value="30">30</option><option value="31">31</option></select> <select name="bdmonth" id="bdmonth" class="dateselector"><option value="">Maand</option><option value="1">Januari</option><option value="2">Februari</option><option value="3">Maart</option><option value="4">April</option><option value="5">Mei</option><option value="6">Juni</option><option value="7">Juli</option><option value="8">Augustus</option><option value="9">September</option><option value="10">Oktober</option><option value="11">November</option><option value="12">December</option></select> <select name="bdyear" id="bdyear" class="dateselector"><option value="">Jaar</option><option value="2010">2010</option><option value="2009">2009</option><option value="2008">2008</option><option value="2007">2007</option><option value="2006">2006</option><option value="2005">2005</option><option value="2004">2004</option><option value="2003">2003</option><option value="2002">2002</option><option value="2001">2001</option><option value="2000">2000</option><option value="1999">1999</option><option value="1998">1998</option><option value="1997">1997</option><option value="1996">1996</option><option value="1995">1995</option><option value="1994">1994</option><option value="1993">1993</option><option value="1992">1992</option><option value="1991">1991</option><option value="1990">1990</option><option value="1989">1989</option><option value="1988">1988</option><option value="1987">1987</option><option value="1986">1986</option><option value="1985">1985</option><option value="1984">1984</option><option value="1983">1983</option><option value="1982">1982</option><option value="1981">1981</option><option value="1980">1980</option><option value="1979">1979</option><option value="1978">1978</option><option value="1977">1977</option><option value="1976">1976</option><option value="1975">1975</option><option value="1974">1974</option><option value="1973">1973</option><option value="1972">1972</option><option value="1971">1971</option><option value="1970">1970</option><option value="1969">1969</option><option value="1968">1968</option><option value="1967">1967</option><option value="1966">1966</option><option value="1965">1965</option><option value="1964">1964</option><option value="1963">1963</option><option value="1962">1962</option><option value="1961">1961</option><option value="1960">1960</option><option value="1959">1959</option><option value="1958">1958</option><option value="1957">1957</option><option value="1956">1956</option><option value="1955">1955</option><option value="1954">1954</option><option value="1953">1953</option><option value="1952">1952</option><option value="1951">1951</option><option value="1950">1950</option><option value="1949">1949</option><option value="1948">1948</option><option value="1947">1947</option><option value="1946">1946</option><option value="1945">1945</option><option value="1944">1944</option><option value="1943">1943</option><option value="1942">1942</option><option value="1941">1941</option><option value="1940">1940</option><option value="1939">1939</option><option value="1938">1938</option><option value="1937">1937</option><option value="1936">1936</option><option value="1935">1935</option><option value="1934">1934</option><option value="1933">1933</option><option value="1932">1932</option><option value="1931">1931</option><option value="1930">1930</option><option value="1929">1929</option><option value="1928">1928</option><option value="1927">1927</option><option value="1926">1926</option><option value="1925">1925</option><option value="1924">1924</option><option value="1923">1923</option><option value="1922">1922</option><option value="1921">1921</option><option value="1920">1920</option><option value="1919">1919</option><option value="1918">1918</option><option value="1917">1917</option><option value="1916">1916</option><option value="1915">1915</option><option value="1914">1914</option><option value="1913">1913</option><option value="1912">1912</option><option value="1911">1911</option><option value="1910">1910</option><option value="1909">1909</option><option value="1908">1908</option><option value="1907">1907</option><option value="1906">1906</option><option value="1905">1905</option><option value="1904">1904</option><option value="1903">1903</option><option value="1902">1902</option><option value="1901">1901</option><option value="1900">1900</option></select>
<br />
<div class="errormsg display_none" id="bd_err"><strong>Ongeldige geboortedatum.</strong></div><br>
<input type="hidden" name="referer" id="referer" value="#referer#" />
<input type="submit" id="reg_submit_button" value="Registreer" onmousedown="this.style.backgroundColor='#ddd';" onmouseup="this.style.backgroundColor='#eee';" onmouseover="this.style.backgroundColor='#eee';" onmouseout="this.style.backgroundColor='#fff';" />
</form>

Regex and POST in same connection

please bear with me, i'm brand new to Python!
I'm trying to login to a website which uses PHP. The form contains two hidden fields, the value of one and the name of another are generated on page load.
My code below successfuly accesses the page and using regex manages to return the values - great!
The problem I am having is that I then generate my querystring that will be used for the POST (this contains the two values obtained earlier) and opens the url again. This generates brand new tokens/values and my originals are of no use.
Can someone shed some light on how I can connect to a site, use regex to get the values and then POST all in the same connection.
I hope i've made myself clear, if not please let me know.
Thanks in advance for your help.
import urllib2,urllib,re,cookielib
url='http://www.example.com/index.php'
req = urllib2.Request(url)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3 Gecko/2008092417 Firefox/3.0.3')
response = urllib2.urlopen(req)
link=response.read()
response.close()
token1=re.compile('<input type="hidden" name="return" value="(.+?)" />').findall(link)
token2=re.compile('<input type="hidden" name="(.+?)" value="1" />').findall(link)
print token1[0]
print token2[0]
username = 'username'
password = 'password'
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
login_data = urllib.urlencode({'username' : username, 'password' : password, 'return' : token1[0], token2[0] : '1', 'Submit' : 'Log in', 'option' : 'com_users', 'task' : 'user.login'})
opener.open('http://www.example.com/index.php', login_data)
resp = opener.open('http://www.example.com/index.php')
FORM:
<form action="/index.php/welcome2" method="post" id="login-form" >
<fieldset class="userdata">
<p id="form-login-username">
<label for="modlgn-username">User Name</label>
<input id="modlgn-username" type="text" name="username" class="inputbox" size="18" />
</p>
<p id="form-login-password">
<label for="modlgn-passwd">Password</label>
<input id="modlgn-passwd" type="password" name="password" class="inputbox" size="18" />
</p>
<p id="form-login-remember">
<label for="modlgn-remember">Remember Me</label>
<input id="modlgn-remember" type="checkbox" name="remember" class="inputbox" value="yes"/>
</p>
<input type="submit" name="Submit" class="button" value="Log in" />
<input type="hidden" name="option" value="com_users" />
<input type="hidden" name="task" value="user.login" />
<input type="hidden" name="return" value="aW5kZXgucGhwP0l0ZW1pZD0xMjc=" />
<input type="hidden" name="c813c34837e4e48e8e3268c0a42912a2" value="1" />
</fieldset>
<ul>
<li>
<a href="/index.php/my-account/my-details?view=reset">
Forgot your password?</a>
</li>
<li>
<a href="/index.php/my-account/my-details?view=remind">
Forgot your username?</a>
</li>
<li>
<a href="/index.php/register">
Create an account</a>
</li>
</ul>
</form>
When you write...
opener.open('http://www.example.com/index.php', login_data)
resp = opener.open('http://www.example.com/index.php')
Why not just this?
resp = opener.open('http://www.example.com/index.php', login_data)
I've never used this Python library, but my first reaction is that this would give you the response text all in one request, with which you can get the new token, wouldn't it?
Update based on form: It looks like your problem is you're POSTing the login info to index.php rather than index.php/welcome.

Invoking a CFC from a FORM

Like the title says, I am invoking a CFC from a FORM. This is how I am doing it now, but there has to be a better way.
Form:
<cfform action="choice.cfm" method="post">
<cfinput type="hidden" name="method" value="DeleteMessage">
<cfinput type="hidden" name="announcement" value="#announcement#">
<cfinput type="hidden" name="ID" value="#ID#">
<cfinput type="submit" value="Delete" name="form.OKbutton1" onclick="return confirm('Are you sure you want to delete?');">
</cfform>
Action page:
<cfif IsDefined("form.OKbutton1")>
<cfinvoke component="pdprojects.scr.changedisablesysequipment"
method="DeleteMessage"
returnvariable="DeleteMessages"
argumentCollection="#Form#" />
</cfif>
I figured out a way to streamline this with jquery and cfc. Page updates fast, and no worries if the person hits back button or refreshes the page. You could probably do a lot more with JQuery to append a div tag instead of location.reload(); (Page Refresh) at the end of the call.
CF Call
<cfajaxproxy cfc="pdprojects.scr.changedisablesysequipment" jsclassname="choice_cls">
Here is the jquery
<script src="/js/jquery-1.7.1.min.js">
<script>
$(document).ready(function(){
$("#OKbutton").click(function(){
if ($('#Announcement').val() == "") {
alert("Please enter message in the text area!");
}
else {
var instance = new choice_cls();
instance.setForm("enterit");
instance.InsertMessage();
location.reload();
}
});
$("#OKbutton1").click(function(){
var instance = new choice_cls();
instance.setForm("deleteit");
instance.DeleteMessage();
location.reload();
});
});
Here is my html
<cfform action="" id="enterit" name="enterit" method="post">
<cfinput type="hidden" value="#session.username#" name="thisname">
<cftextarea cols="50" rows="8" name="Announcement"></cftextarea><br>
<cfinput type="button" value="Enter Announcement" name="OKbutton" id="OKbutton">
</cfform>
<cfform action="" id="deleteit" name="deleteit" method="post">
<cfinput type="hidden" name="method" value="DeleteMessage">
<cfinput type="hidden" name="announcement" value="#announcement#">
<cfinput type="hidden" name="ID" value="#ID#">
<cfinput type="button" value="Delete" name="OKbutton1" onclick="return confirm('Are you sure you want to delete?');">
</cfform>
Then just create your CFC for coldfusion!